summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/arm/nvidia/tegra_parameters.txt10
-rw-r--r--Documentation/driver-model/devres.txt4
-rw-r--r--arch/arm/Kconfig16
-rw-r--r--arch/arm/configs/tegra3_android_defconfig14
-rw-r--r--arch/arm/configs/tegra3_defconfig5
-rw-r--r--arch/arm/configs/tegra_android_defconfig3
-rw-r--r--arch/arm/configs/tegra_defconfig5
-rw-r--r--arch/arm/configs/tegra_p1852_gnu_linux_defconfig22
-rw-r--r--arch/arm/configs/tegra_p852_gnu_linux_defconfig1
-rw-r--r--arch/arm/include/asm/proc-fns.h8
-rw-r--r--arch/arm/include/asm/suspend.h17
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/sleep.S90
-rw-r--r--arch/arm/kernel/suspend.c72
-rw-r--r--arch/arm/mach-tegra/Kconfig23
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/apbio.c24
-rw-r--r--arch/arm/mach-tegra/apbio.h12
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power.c807
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power.h22
-rw-r--r--arch/arm/mach-tegra/baseband-xmm-power2.c525
-rw-r--r--arch/arm/mach-tegra/board-aruba-panel.c2
-rw-r--r--arch/arm/mach-tegra/board-cardhu-kbc.c7
-rw-r--r--arch/arm/mach-tegra/board-cardhu-memory.c360
-rw-r--r--arch/arm/mach-tegra/board-cardhu-panel.c13
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pinmux.c8
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c8
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c15
-rw-r--r--arch/arm/mach-tegra/board-cardhu-power.c27
-rw-r--r--arch/arm/mach-tegra/board-cardhu-sdhci.c57
-rw-r--r--arch/arm/mach-tegra/board-cardhu-sensors.c117
-rw-r--r--arch/arm/mach-tegra/board-cardhu.c65
-rw-r--r--arch/arm/mach-tegra/board-cardhu.h2
-rw-r--r--arch/arm/mach-tegra/board-enterprise-memory.c735
-rw-r--r--arch/arm/mach-tegra/board-enterprise-panel.c74
-rw-r--r--arch/arm/mach-tegra/board-enterprise-pinmux.c2
-rw-r--r--arch/arm/mach-tegra/board-enterprise-power.c15
-rw-r--r--arch/arm/mach-tegra/board-enterprise-sdhci.c29
-rw-r--r--arch/arm/mach-tegra/board-enterprise.c17
-rw-r--r--arch/arm/mach-tegra/board-harmony-panel.c2
-rw-r--r--arch/arm/mach-tegra/board-harmony.c6
-rw-r--r--arch/arm/mach-tegra/board-kai-memory.c148
-rw-r--r--arch/arm/mach-tegra/board-kai-panel.c21
-rw-r--r--arch/arm/mach-tegra/board-kai-pinmux.c3
-rw-r--r--arch/arm/mach-tegra/board-kai-power.c8
-rw-r--r--arch/arm/mach-tegra/board-kai-sdhci.c48
-rw-r--r--arch/arm/mach-tegra/board-kai-sensors.c120
-rw-r--r--arch/arm/mach-tegra/board-kai.c9
-rw-r--r--arch/arm/mach-tegra/board-kai.h2
-rw-r--r--arch/arm/mach-tegra/board-p1852-panel.c2
-rw-r--r--arch/arm/mach-tegra/board-p1852-pinmux.c4
-rw-r--r--arch/arm/mach-tegra/board-p1852.c17
-rw-r--r--arch/arm/mach-tegra/board-touch-raydium_spi.c6
-rw-r--r--arch/arm/mach-tegra/board-touch.h25
-rw-r--r--arch/arm/mach-tegra/board-ventana-panel.c28
-rw-r--r--arch/arm/mach-tegra/board-ventana-pinmux.c4
-rw-r--r--arch/arm/mach-tegra/board-ventana-power.c4
-rw-r--r--arch/arm/mach-tegra/board-ventana-sdhci.c23
-rw-r--r--arch/arm/mach-tegra/board-ventana-sensors.c20
-rw-r--r--arch/arm/mach-tegra/board-whistler-panel.c21
-rw-r--r--arch/arm/mach-tegra/board-whistler-pinmux.c14
-rw-r--r--arch/arm/mach-tegra/board-whistler-sdhci.c23
-rw-r--r--arch/arm/mach-tegra/board-whistler.c3
-rw-r--r--arch/arm/mach-tegra/board.h27
-rw-r--r--arch/arm/mach-tegra/clock.c32
-rw-r--r--arch/arm/mach-tegra/clock.h1
-rw-r--r--arch/arm/mach-tegra/common.c237
-rw-r--r--arch/arm/mach-tegra/cpu-tegra3.c14
-rw-r--r--arch/arm/mach-tegra/cpuidle-t2.c5
-rw-r--r--arch/arm/mach-tegra/cpuidle-t3.c3
-rw-r--r--arch/arm/mach-tegra/devices.c4
-rw-r--r--arch/arm/mach-tegra/dma.c14
-rw-r--r--arch/arm/mach-tegra/dvfs.h2
-rw-r--r--arch/arm/mach-tegra/fuse.c74
-rw-r--r--arch/arm/mach-tegra/headsmp.S8
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h7
-rw-r--r--arch/arm/mach-tegra/include/mach/dma.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/hdmi-audio.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h10
-rw-r--r--arch/arm/mach-tegra/include/mach/sdhci.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h6
-rw-r--r--arch/arm/mach-tegra/include/mach/thermal.h6
-rw-r--r--arch/arm/mach-tegra/io.c6
-rw-r--r--arch/arm/mach-tegra/iovmm-smmu.c52
-rw-r--r--arch/arm/mach-tegra/p852/board-p852-panel.c2
-rw-r--r--arch/arm/mach-tegra/pcie.c23
-rw-r--r--arch/arm/mach-tegra/pinmux-t2-tables.c4
-rw-r--r--arch/arm/mach-tegra/pinmux-t3-tables.c442
-rw-r--r--arch/arm/mach-tegra/platsmp.c5
-rw-r--r--arch/arm/mach-tegra/pm.c89
-rw-r--r--arch/arm/mach-tegra/powergate.c6
-rw-r--r--arch/arm/mach-tegra/sleep-t2.S47
-rw-r--r--arch/arm/mach-tegra/sleep-t3.S34
-rw-r--r--arch/arm/mach-tegra/sleep.S269
-rw-r--r--arch/arm/mach-tegra/sleep.h69
-rw-r--r--arch/arm/mach-tegra/syncpt.c100
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c167
-rw-r--r--arch/arm/mach-tegra/tegra3_clocks.c45
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c126
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.c71
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.h3
-rw-r--r--arch/arm/mach-tegra/tegra3_speedo.c37
-rw-r--r--arch/arm/mach-tegra/tegra3_thermal.c97
-rw-r--r--arch/arm/mach-tegra/tegra3_throttle.c153
-rw-r--r--arch/arm/mach-tegra/tegra_usb_modem_power.c232
-rw-r--r--arch/arm/mach-tegra/usb_phy.c24
-rw-r--r--arch/arm/mach-tegra/wdt-recovery.c2
-rw-r--r--arch/arm/mm/cache-l2x0.c2
-rw-r--r--arch/arm/mm/proc-arm920.S21
-rw-r--r--arch/arm/mm/proc-arm926.S21
-rw-r--r--arch/arm/mm/proc-sa1100.S25
-rw-r--r--arch/arm/mm/proc-v6.S44
-rw-r--r--arch/arm/mm/proc-v7.S74
-rw-r--r--arch/arm/mm/proc-xsc3.S28
-rw-r--r--arch/arm/mm/proc-xscale.S25
-rw-r--r--arch/arm/oprofile/common.c22
-rw-r--r--arch/arm/vfp/vfpmodule.c10
-rw-r--r--drivers/base/regmap/Kconfig3
-rw-r--r--drivers/base/regmap/Makefile1
-rw-r--r--drivers/base/regmap/internal.h24
-rw-r--r--drivers/base/regmap/regcache-lzo.c27
-rw-r--r--drivers/base/regmap/regcache-rbtree.c79
-rw-r--r--drivers/base/regmap/regcache.c113
-rw-r--r--drivers/base/regmap/regmap-debugfs.c93
-rw-r--r--drivers/base/regmap/regmap-i2c.c13
-rw-r--r--drivers/base/regmap/regmap-irq.c37
-rw-r--r--drivers/base/regmap/regmap-mmio.c224
-rw-r--r--drivers/base/regmap/regmap-spi.c13
-rw-r--r--drivers/base/regmap/regmap.c234
-rw-r--r--drivers/bluetooth/ti_bluesleep.c120
-rw-r--r--drivers/clk/clkdev.c45
-rw-r--r--drivers/cpufreq/cpufreq.c57
-rw-r--r--drivers/crypto/tegra-aes.c11
-rw-r--r--drivers/gpio/gpio-tegra.c14
-rw-r--r--drivers/gpu/ion/tegra/tegra_ion.c2
-rw-r--r--drivers/hid/hid-sony.c25
-rw-r--r--drivers/hwmon/tegra-tsensor.c4
-rw-r--r--drivers/i2c/busses/i2c-tegra.c40
-rw-r--r--drivers/input/touchscreen/rmi4/rmi_bus.c16
-rw-r--r--drivers/input/touchscreen/rmi4/rmi_f09.c20
-rw-r--r--drivers/input/touchscreen/rmi4/rmi_spi.c13
-rw-r--r--drivers/iommu/tegra-gart.c2
-rw-r--r--drivers/iommu/tegra-smmu.c2
-rw-r--r--drivers/media/video/tegra/Kconfig7
-rw-r--r--drivers/media/video/tegra/Makefile1
-rw-r--r--drivers/media/video/tegra/ad5820.c2
-rw-r--r--drivers/media/video/tegra/ar0832_main.c9
-rw-r--r--drivers/media/video/tegra/avp/avp.c2
-rw-r--r--drivers/media/video/tegra/avp/avp_svc.c2
-rw-r--r--drivers/media/video/tegra/nvavp/nvavp_dev.c48
-rw-r--r--drivers/media/video/tegra/ov14810.c2
-rw-r--r--drivers/media/video/tegra/ov2710.c2
-rw-r--r--drivers/media/video/tegra/ov5640.c491
-rw-r--r--drivers/media/video/tegra/ov5640_tables.h4582
-rw-r--r--drivers/media/video/tegra/ov5650.c98
-rw-r--r--drivers/media/video/tegra/ov9726.c1
-rw-r--r--drivers/media/video/tegra/sh532u.c871
-rw-r--r--drivers/media/video/tegra/soc380.c1
-rw-r--r--drivers/media/video/tegra/tegra_camera.c306
-rw-r--r--drivers/mfd/max77663-core.c8
-rw-r--r--drivers/mfd/max8907c.c15
-rw-r--r--drivers/mfd/tps80031.c18
-rw-r--r--drivers/misc/bcm4329_rfkill.c7
-rw-r--r--drivers/misc/nct1008.c38
-rw-r--r--drivers/misc/tegra-cryptodev.c173
-rw-r--r--drivers/misc/tegra-cryptodev.h15
-rw-r--r--drivers/mmc/card/Kconfig10
-rw-r--r--drivers/mmc/card/block.c3
-rw-r--r--drivers/mmc/card/mmc_test.c2
-rw-r--r--drivers/mmc/core/core.c5
-rw-r--r--drivers/mmc/core/mmc_ops.c2
-rw-r--r--drivers/mmc/host/sdhci-tegra.c83
-rw-r--r--drivers/mmc/host/sdhci.c28
-rw-r--r--drivers/mmc/host/sdhci.h1
-rw-r--r--drivers/mmc/host/sh_mmcif.c5
-rw-r--r--drivers/mmc/host/tmio_mmc_dma.c5
-rw-r--r--drivers/mtd/maps/tegra_nor.c2
-rw-r--r--drivers/net/usb/cdc_ether.c9
-rw-r--r--drivers/net/usb/cdc_subset.c5
-rw-r--r--drivers/net/usb/raw_ip_net.c191
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile3
-rw-r--r--drivers/net/wireless/bcmdhd/Kconfig7
-rw-r--r--drivers/net/wireless/bcmdhd/Makefile4
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c2
-rw-r--r--drivers/net/wireless/sd8797/Kconfig39
-rw-r--r--drivers/net/wireless/sd8797/Makefile176
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan.h35
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11d.c1515
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11h.c3208
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11h.h158
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n.c1936
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n.h420
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.c509
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n_aggr.h37
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.c1138
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_11n_rxreorder.h102
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_cfp.c1378
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_cmdevt.c2934
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_decl.h893
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_fw.h4672
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_ieee.h1322
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_init.c1043
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_init.h88
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_ioctl.h2981
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_join.c1853
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_join.h40
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_main.h2742
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_meas.c464
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_meas.h54
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_misc.c2156
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_module.c47
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_scan.c4223
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sdio.c1661
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sdio.h307
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_shim.c946
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_cmd.c1996
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_cmdresp.c1726
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_event.c589
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_ioctl.c5489
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_rx.c289
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_sta_tx.c277
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_txrx.c376
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_uap.h104
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_uap_cmdevent.c3021
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_uap_ioctl.c1393
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_uap_txrx.c556
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_util.h526
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_wmm.c2521
-rw-r--r--drivers/net/wireless/sd8797/mlan/mlan_wmm.h182
-rw-r--r--drivers/net/wireless/sd8797/mlinux/mlan.h35
-rw-r--r--drivers/net/wireless/sd8797/mlinux/mlan_decl.h893
-rw-r--r--drivers/net/wireless/sd8797/mlinux/mlan_ieee.h1322
-rw-r--r--drivers/net/wireless/sd8797/mlinux/mlan_ioctl.h2981
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_cfg80211.c1687
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_cfg80211.h203
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_debug.c674
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.c2176
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_eth_ioctl.h90
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_ioctl.c4463
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_main.c4036
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_main.h1564
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_priv.c6690
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_priv.h729
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_proc.c631
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_sdio.h140
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_sdio_mmc.c734
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_shim.c1527
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_shim.h95
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.c2520
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_sta_cfg80211.h41
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap.c2692
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap.h410
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.c1288
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap_cfg80211.h30
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap_priv.c175
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap_priv.h194
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_uap_wext.c1766
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_wext.c3051
-rw-r--r--drivers/net/wireless/sd8797/mlinux/moal_wext.h115
-rw-r--r--drivers/power/bq27x00_battery.c6
-rw-r--r--drivers/power/max17048_battery.c31
-rw-r--r--drivers/power/smb349-charger.c42
-rw-r--r--drivers/regulator/Kconfig19
-rw-r--r--drivers/regulator/Makefile2
-rw-r--r--drivers/regulator/core.c62
-rw-r--r--drivers/regulator/max77663-regulator.c12
-rw-r--r--drivers/regulator/max8973-regulator.c606
-rw-r--r--drivers/regulator/tps6238x0-regulator.c470
-rw-r--r--drivers/rtc/rtc-tps6591x.c90
-rw-r--r--drivers/spi/spi-tegra.c22
-rw-r--r--drivers/spi/spi-topcliff-pch.c5
-rw-r--r--drivers/tty/serial/amba-pl011.c5
-rw-r--r--drivers/tty/serial/pch_uart.c5
-rw-r--r--drivers/tty/serial/sh-sci.c5
-rw-r--r--drivers/tty/serial/tegra_hsuart.c2
-rw-r--r--drivers/usb/class/cdc-acm.c16
-rw-r--r--drivers/usb/gadget/Kconfig11
-rw-r--r--drivers/usb/gadget/Makefile4
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c200
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.h3
-rw-r--r--drivers/usb/gadget/gadget_chips.h4
-rw-r--r--drivers/usb/gadget/tegra_udc.c2867
-rw-r--r--drivers/usb/gadget/tegra_udc.h440
-rw-r--r--drivers/usb/gadget/udc-core.c4
-rw-r--r--drivers/usb/host/ehci-tegra.c100
-rw-r--r--drivers/usb/host/ehci.h2
-rw-r--r--drivers/usb/otg/tegra-otg.c269
-rw-r--r--drivers/usb/serial/baseband_usb_chr.c548
-rw-r--r--drivers/usb/serial/baseband_usb_chr.h9
-rw-r--r--drivers/video/mx3fb.c5
-rw-r--r--drivers/video/tegra/Kconfig18
-rw-r--r--drivers/video/tegra/dc/Makefile1
-rw-r--r--drivers/video/tegra/dc/dc.c374
-rw-r--r--drivers/video/tegra/dc/dc_config.c246
-rw-r--r--drivers/video/tegra/dc/dc_config.h148
-rw-r--r--drivers/video/tegra/dc/dc_priv.h19
-rw-r--r--drivers/video/tegra/dc/dc_reg.h6
-rw-r--r--drivers/video/tegra/dc/dsi.c128
-rw-r--r--drivers/video/tegra/dc/ext/Makefile1
-rw-r--r--drivers/video/tegra/dc/ext/dev.c41
-rw-r--r--drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h2
-rw-r--r--drivers/video/tegra/dc/ext/util.c2
-rw-r--r--drivers/video/tegra/dc/hdmi.c182
-rw-r--r--drivers/video/tegra/dc/rgb.c8
-rw-r--r--drivers/video/tegra/fb.c53
-rw-r--r--drivers/video/tegra/host/Makefile3
-rw-r--r--drivers/video/tegra/host/bus.c82
-rw-r--r--drivers/video/tegra/host/bus.h38
-rw-r--r--drivers/video/tegra/host/bus_client.c72
-rw-r--r--drivers/video/tegra/host/chip_support.c56
-rw-r--r--drivers/video/tegra/host/chip_support.h33
-rw-r--r--drivers/video/tegra/host/debug.c20
-rw-r--r--drivers/video/tegra/host/dev.c96
-rw-r--r--drivers/video/tegra/host/dev.h16
-rw-r--r--drivers/video/tegra/host/dsi/dsi.c3
-rw-r--r--drivers/video/tegra/host/gr2d/gr2d.c3
-rw-r--r--drivers/video/tegra/host/gr3d/gr3d.c85
-rw-r--r--drivers/video/tegra/host/gr3d/gr3d_t20.c6
-rw-r--r--drivers/video/tegra/host/gr3d/gr3d_t30.c8
-rw-r--r--drivers/video/tegra/host/host1x/host1x_cdma.c203
-rw-r--r--drivers/video/tegra/host/host1x/host1x_cdma.h2
-rw-r--r--drivers/video/tegra/host/host1x/host1x_channel.c21
-rw-r--r--drivers/video/tegra/host/host1x/host1x_debug.c17
-rw-r--r--drivers/video/tegra/host/host1x/host1x_hwctx.h1
-rw-r--r--drivers/video/tegra/host/host1x/host1x_intr.c77
-rw-r--r--drivers/video/tegra/host/host1x/host1x_syncpt.c34
-rw-r--r--drivers/video/tegra/host/host1x/host1x_syncpt.h5
-rw-r--r--drivers/video/tegra/host/isp/isp.c3
-rw-r--r--drivers/video/tegra/host/mpe/mpe.c61
-rw-r--r--drivers/video/tegra/host/nvhost_acm.c55
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.c142
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.h10
-rw-r--r--drivers/video/tegra/host/nvhost_channel.c49
-rw-r--r--drivers/video/tegra/host/nvhost_channel.h35
-rw-r--r--drivers/video/tegra/host/nvhost_hwctx.h2
-rw-r--r--drivers/video/tegra/host/nvhost_intr.c48
-rw-r--r--drivers/video/tegra/host/nvhost_intr.h1
-rw-r--r--drivers/video/tegra/host/nvhost_job.c7
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.c55
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.h11
-rw-r--r--drivers/video/tegra/host/t20/t20.c71
-rw-r--r--drivers/video/tegra/host/t20/t20.h11
-rw-r--r--drivers/video/tegra/host/t30/t30.c84
-rw-r--r--drivers/video/tegra/host/t30/t30.h9
-rw-r--r--drivers/video/tegra/host/vi/vi.c3
-rw-r--r--drivers/video/tegra/nvmap/nvmap.c2
-rw-r--r--drivers/video/tegra/nvmap/nvmap.h10
-rw-r--r--drivers/video/tegra/nvmap/nvmap_dev.c6
-rw-r--r--drivers/video/tegra/nvmap/nvmap_handle.c33
-rw-r--r--drivers/video/tegra/nvmap/nvmap_heap.c2
-rw-r--r--drivers/video/tegra/nvmap/nvmap_ioctl.c2
-rw-r--r--drivers/video/tegra/nvmap/nvmap_ioctl.h2
-rw-r--r--include/linux/bitops.h6
-rw-r--r--include/linux/clk.h32
-rw-r--r--include/linux/cpufreq.h1
-rw-r--r--include/linux/device.h21
-rw-r--r--include/linux/i2c.h13
-rw-r--r--include/linux/i2c/twl.h16
-rwxr-xr-xinclude/linux/interrupt_keys.h47
-rw-r--r--include/linux/nct1008.h3
-rw-r--r--include/linux/nvhost.h62
-rw-r--r--include/linux/nvmap.h (renamed from arch/arm/mach-tegra/include/mach/nvmap.h)7
-rw-r--r--include/linux/platform_device.h9
-rw-r--r--include/linux/regmap.h31
-rw-r--r--include/linux/regulator/gpio-switch-regulator.h69
-rw-r--r--include/linux/regulator/max8973-regulator.h77
-rw-r--r--include/linux/regulator/tps6238x0-regulator.h46
-rw-r--r--include/linux/smb349-charger.h2
-rw-r--r--include/linux/tegra_audio.h2
-rw-r--r--include/linux/wl12xx.h4
-rw-r--r--include/media/nvc.h1
-rw-r--r--include/media/ov5640.h64
-rw-r--r--include/media/ov5650.h6
-rw-r--r--include/media/sh532u.h44
-rw-r--r--include/media/tegra_camera.h3
-rw-r--r--include/trace/events/nvhost.h65
-rw-r--r--include/trace/events/power.h22
-rw-r--r--include/trace/events/regmap.h36
-rw-r--r--include/video/tegra_dc_ext.h5
-rw-r--r--security/tf_driver/s_version.h4
-rw-r--r--security/tf_driver/tf_comm.c56
-rw-r--r--security/tf_driver/tf_device.c19
-rw-r--r--sound/pci/hda/hda_eld.c5
-rw-r--r--sound/pci/hda/patch_hdmi.c6
-rw-r--r--sound/soc/codecs/Makefile3
-rw-r--r--sound/soc/codecs/aic326x_tiload.c5
-rw-r--r--sound/soc/codecs/base_main_Rate48_pps_driver.h11
-rw-r--r--sound/soc/codecs/rt5639.c16
-rw-r--r--sound/soc/codecs/rt5640.c47
-rw-r--r--sound/soc/codecs/second_rate_pps_driver.h7
-rw-r--r--sound/soc/codecs/spdif_transciever.c38
-rw-r--r--sound/soc/codecs/tlv320aic326x.c24
-rw-r--r--sound/soc/codecs/tlv320aic326x.h11
-rw-r--r--sound/soc/codecs/tlv320aic326x_mini-dsp.c32
-rw-r--r--sound/soc/codecs/tlv320aic326x_minidsp_config.c11
-rw-r--r--sound/soc/codecs/wm8903.c8
-rw-r--r--sound/soc/sh/siu_pcm.c5
-rw-r--r--sound/soc/tegra/Makefile2
-rw-r--r--sound/soc/tegra/tegra20_i2s.c3
-rw-r--r--sound/soc/tegra/tegra30_ahub.c127
-rw-r--r--sound/soc/tegra/tegra30_ahub.h14
-rw-r--r--sound/soc/tegra/tegra30_i2s.c241
-rw-r--r--sound/soc/tegra/tegra30_i2s.h14
-rw-r--r--sound/soc/tegra/tegra_aic326x.c8
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c4
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h3
-rw-r--r--sound/soc/tegra/tegra_max98088.c20
-rw-r--r--sound/soc/tegra/tegra_max98095.c2
-rw-r--r--sound/soc/tegra/tegra_p1852.c2
-rw-r--r--sound/soc/tegra/tegra_pcm.c107
-rw-r--r--sound/soc/tegra/tegra_pcm.h20
-rw-r--r--sound/soc/tegra/tegra_rt5640.c59
-rw-r--r--sound/soc/tegra/tegra_tdm_pcm.c160
-rw-r--r--sound/soc/tegra/tegra_wm8753.c2
-rw-r--r--sound/soc/tegra/tegra_wm8903.c2
-rw-r--r--sound/soc/tegra/trimslice.c2
417 files changed, 121239 insertions, 5245 deletions
diff --git a/Documentation/arm/nvidia/tegra_parameters.txt b/Documentation/arm/nvidia/tegra_parameters.txt
index 4c73fe7..39ab662 100644
--- a/Documentation/arm/nvidia/tegra_parameters.txt
+++ b/Documentation/arm/nvidia/tegra_parameters.txt
@@ -167,3 +167,13 @@ Contains voltage state.
/sys/kernel/debug/clock/mon.avp/rate
------------------------------------
+
+/sys/kernel/debug/clock/rails
+-----------------------------
+
+Contains the time at each voltage.
+
+/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
+--------------------------------------------------------
+
+Contains the time at each frequency.
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 10c64c8..6346042 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -267,3 +267,7 @@ IOMAP
pcim_iounmap()
pcim_iomap_table() : array of mapped addresses indexed by BAR
pcim_iomap_regions() : do request_region() and iomap() on multiple BARs
+
+CLOCK
+ devm_clk_get()
+ devm_clk_put()
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3c3b868..5132b50 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1155,6 +1155,14 @@ config ARM_ERRATA_460075
ACTLR register. Note that setting specific bits in the ACTLR register
may not be available in non-secure mode.
+config ARM_ERRATA_716044
+ bool "ARM errata: an uncacheable load multiple instruction can cause a deadlock"
+ depends on CPU_V7
+ help
+ Under some rare circumstances, an uncacheable load multiple
+ instruction (LDRD, LDM, VLDM, VLD1, VLD2, VLD3, VLD4) can cause
+ a processor deadlock.
+
config ARM_ERRATA_742230
bool "ARM errata: DMB operation may be faulty"
depends on CPU_V7 && SMP
@@ -1688,6 +1696,14 @@ config HW_PERF_EVENTS
Enable hardware performance counter support for perf events. If
disabled, perf events will use software events only.
+config ARCH_HAS_SUSPEND_PAGETABLE
+ bool
+ help
+ This option indicates the platform architecture installs its own
+ 1:1 pagetable during CPU suspend/resume codepaths. This means the
+ patching of the pagetable as part of reenabling the MMU isn't
+ needed in the ARM common CPU resume codepath. If in doubt, say N.
+
source "mm/Kconfig"
config FORCE_MAX_ZONEORDER
diff --git a/arch/arm/configs/tegra3_android_defconfig b/arch/arm/configs/tegra3_android_defconfig
index 92a9e94..ba20b0e 100644
--- a/arch/arm/configs/tegra3_android_defconfig
+++ b/arch/arm/configs/tegra3_android_defconfig
@@ -234,6 +234,8 @@ CONFIG_BCMDHD_WIFI_CONTROL_FUNC=y
CONFIG_BCMDHD_HW_OOB=y
CONFIG_BCMDHD_CSCAN_ENABLE=y
CONFIG_BCMDHD_INSMOD_NO_FW_LOAD=y
+# CONFIG_BCMDHD_CUSTOM_REGULATORY_DOMAIN is not set
+CONFIG_SD8797=m
CONFIG_WL12XX_MENU=m
CONFIG_WL12XX=m
CONFIG_WL12XX_SDIO=m
@@ -311,10 +313,14 @@ CONFIG_MFD_RICOH583=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+CONFIG_REGULATOR_MAX8973=y
CONFIG_REGULATOR_MAX77663=y
CONFIG_REGULATOR_TPS6586X=y
CONFIG_REGULATOR_TPS65910=y
CONFIG_REGULATOR_TPS62360=y
+CONFIG_REGULATOR_TPS6238X0=y
CONFIG_REGULATOR_TPS6591X=y
CONFIG_REGULATOR_TPS80031=y
CONFIG_REGULATOR_RICOH583=y
@@ -327,6 +333,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
# CONFIG_TEGRA_MEDIASERVER is not set
CONFIG_TEGRA_NVAVP=y
CONFIG_VIDEO_OV5650=y
+CONFIG_VIDEO_OV5640=y
CONFIG_VIDEO_OV9726=y
CONFIG_VIDEO_OV2710=y
CONFIG_VIDEO_AR0832=y
@@ -379,7 +386,7 @@ CONFIG_USB_SERIAL_OPTION=y
CONFIG_USB_SERIAL_BASEBAND=m
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_FSL_USB2=y
+CONFIG_USB_TEGRA=y
CONFIG_USB_G_ANDROID=y
CONFIG_USB_TEGRA_OTG=y
CONFIG_MMC=y
@@ -434,6 +441,7 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DEBUG_FS=y
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_DETECT_HUNG_TASK is not set
@@ -442,6 +450,10 @@ CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_VM=y
+CONFIG_FUNCTION_TRACER=y
+# CONFIG_FUNCTION_GRAPH_TRACER is not set
+CONFIG_TRACEDUMP=y
+CONFIG_TRACEDUMP_PROCFS=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_SHA256=y
diff --git a/arch/arm/configs/tegra3_defconfig b/arch/arm/configs/tegra3_defconfig
index cb78209..2d895fe 100644
--- a/arch/arm/configs/tegra3_defconfig
+++ b/arch/arm/configs/tegra3_defconfig
@@ -39,6 +39,7 @@ CONFIG_TEGRA_BB_XMM_POWER=y
CONFIG_TEGRA_BB_XMM_POWER2=m
CONFIG_TEGRA_PLLM_RESTRICTED=y
CONFIG_TEGRA_PREINIT_CLOCKS=y
+CONFIG_TEGRA_PREPOWER_WIFI=y
CONFIG_ARM_ERRATA_742230=y
CONFIG_ARM_ERRATA_743622=y
CONFIG_ARM_ERRATA_751472=y
@@ -192,7 +193,6 @@ CONFIG_AD525X_DPOT_I2C=y
CONFIG_ICS932S401=y
CONFIG_APDS9802ALS=y
CONFIG_ISL29003=y
-CONFIG_SENSORS_AK8975=y
CONFIG_SENSORS_NCT1008=y
CONFIG_UID_STAT=y
CONFIG_BCM4329_RFKILL=y
@@ -300,6 +300,7 @@ CONFIG_MFD_RICOH583=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
CONFIG_REGULATOR_MAX8907C=y
CONFIG_REGULATOR_MAX77663=y
CONFIG_REGULATOR_TPS6586X=y
@@ -364,7 +365,7 @@ CONFIG_USB_SERIAL_OPTION=y
CONFIG_USB_SERIAL_BASEBAND=m
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_FSL_USB2=y
+CONFIG_USB_TEGRA=y
CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_TEGRA_OTG=y
CONFIG_MMC=y
diff --git a/arch/arm/configs/tegra_android_defconfig b/arch/arm/configs/tegra_android_defconfig
index 053b374..a129a8e 100644
--- a/arch/arm/configs/tegra_android_defconfig
+++ b/arch/arm/configs/tegra_android_defconfig
@@ -214,6 +214,7 @@ CONFIG_BCMDHD_WIFI_CONTROL_FUNC=y
CONFIG_BCMDHD_HW_OOB=y
CONFIG_BCMDHD_CSCAN_ENABLE=y
CONFIG_BCMDHD_INSMOD_NO_FW_LOAD=y
+# CONFIG_BCMDHD_CUSTOM_REGULATORY_DOMAIN is not set
CONFIG_USB_USBNET=y
# CONFIG_USB_NET_NET1080 is not set
# CONFIG_USB_BELKIN is not set
@@ -323,7 +324,7 @@ CONFIG_USB_SERIAL_PL2303=y
CONFIG_USB_SERIAL_OPTION=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_FSL_USB2=y
+CONFIG_USB_TEGRA=y
CONFIG_USB_G_ANDROID=y
CONFIG_USB_TEGRA_OTG=y
CONFIG_MMC=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 6e51d191a..aa9f7df 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -37,6 +37,8 @@ CONFIG_TEGRA_EMC_SCALING_ENABLE=y
CONFIG_TEGRA_CLOCK_DEBUG_WRITE=y
CONFIG_USB_HOTPLUG=y
CONFIG_TEGRA_USB_MODEM_POWER=y
+CONFIG_TEGRA_PREINIT_CLOCKS=y
+CONFIG_TEGRA_PREPOWER_WIFI=y
CONFIG_ARM_ERRATA_720789=y
CONFIG_ARM_ERRATA_751472=y
CONFIG_NO_HZ=y
@@ -189,7 +191,6 @@ CONFIG_AD525X_DPOT=y
CONFIG_AD525X_DPOT_I2C=y
CONFIG_APDS9802ALS=y
CONFIG_ISL29003=y
-CONFIG_SENSORS_AK8975=y
CONFIG_SENSORS_NCT1008=y
CONFIG_UID_STAT=y
CONFIG_BCM4329_RFKILL=y
@@ -327,7 +328,7 @@ CONFIG_USB_SERIAL_PL2303=y
CONFIG_USB_SERIAL_OPTION=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_FSL_USB2=y
+CONFIG_USB_TEGRA=y
CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_TEGRA_OTG=y
CONFIG_MMC=y
diff --git a/arch/arm/configs/tegra_p1852_gnu_linux_defconfig b/arch/arm/configs/tegra_p1852_gnu_linux_defconfig
index 594b078..6a98b5b 100644
--- a/arch/arm/configs/tegra_p1852_gnu_linux_defconfig
+++ b/arch/arm/configs/tegra_p1852_gnu_linux_defconfig
@@ -13,12 +13,11 @@ CONFIG_RESOURCE_COUNTERS=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_PANIC_TIMEOUT=10
-CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_ELF_CORE is not set
CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
@@ -27,20 +26,21 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_TEGRA=y
+CONFIG_GPIO_PCA953X=y
CONFIG_ARCH_TEGRA_3x_SOC=y
CONFIG_TEGRA_PCI=y
CONFIG_MACH_P1852=y
-CONFIG_TEGRA_DEBUG_UARTB=y
CONFIG_TEGRA_PWM=y
# CONFIG_TEGRA_CPU_DVFS is not set
CONFIG_TEGRA_CLOCK_DEBUG_WRITE=y
-CONFIG_TEGRA_MC_PROFILE=y
+# CONFIG_TEGRA_MC_EARLY_ACK is not set
CONFIG_ARM_ERRATA_743622=y
CONFIG_ARM_ERRATA_751472=y
CONFIG_ARM_ERRATA_752520=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
+CONFIG_HOTPLUG_CPU=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
@@ -50,6 +50,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="mem=448@2048M console=ttyS0,115200n8 earlyprintk init=/bin/ash"
CONFIG_VFP=y
CONFIG_NEON=y
+# CONFIG_SUSPEND is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -75,7 +76,6 @@ CONFIG_IPV6_MULTIPLE_TABLES=y
# CONFIG_ANDROID_PARANOID_NETWORK is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
@@ -88,7 +88,6 @@ CONFIG_MTD_NOR_TEGRA=y
CONFIG_MTD_NAND_TEGRA=y
CONFIG_MTD_NAND=y
CONFIG_BLK_DEV_LOOP=y
-# CONFIG_ANDROID_PMEM is not set
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_LOWLEVEL is not set
@@ -112,10 +111,10 @@ CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_TEGRA=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_TEGRA=y
-# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y
@@ -126,7 +125,6 @@ CONFIG_SPI_TEGRA=y
CONFIG_SPI_SLAVE_TEGRA=y
CONFIG_SPI_SPIDEV=y
CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PCA953X=y
CONFIG_POWER_SUPPLY=y
CONFIG_PDA_POWER=y
CONFIG_BATTERY_BQ20Z75=y
@@ -167,18 +165,19 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_LIBUSUAL=y
CONFIG_USB_TEGRA_OTG=y
CONFIG_MMC=y
+CONFIG_MMC_BKOPS=y
CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MMC_EMBEDDED_SDIO=y
CONFIG_MMC_PARANOID_SD_INIT=y
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_SWITCH=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_TEGRA=y
CONFIG_STAGING=y
-# CONFIG_STAGING_EXCLUDE_BUILD is not set
CONFIG_IIO=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
@@ -198,7 +197,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_ROOT_NFS=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_EFI_PARTITION=y
CONFIG_NLS_CODEPAGE_437=y
@@ -206,17 +204,13 @@ CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_VM=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_ARM_UNWIND is not set
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ARC4=y
diff --git a/arch/arm/configs/tegra_p852_gnu_linux_defconfig b/arch/arm/configs/tegra_p852_gnu_linux_defconfig
index 7539158..9f7e717 100644
--- a/arch/arm/configs/tegra_p852_gnu_linux_defconfig
+++ b/arch/arm/configs/tegra_p852_gnu_linux_defconfig
@@ -248,6 +248,7 @@ CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_PL2303=y
CONFIG_USB_TEGRA_OTG=y
CONFIG_MMC=y
+CONFIG_MMC_BKOPS=y
CONFIG_MMC_UNSAFE_RESUME=y
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_SDHCI=y
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 9e92cb20..633d1cb 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -81,10 +81,6 @@ extern void cpu_dcache_clean_area(void *, int);
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
-
-/* These three are private to arch/arm/kernel/suspend.c */
-extern void cpu_do_suspend(void *);
-extern void cpu_do_resume(void *);
#else
#define cpu_proc_init processor._proc_init
#define cpu_proc_fin processor._proc_fin
@@ -93,10 +89,6 @@ extern void cpu_do_resume(void *);
#define cpu_dcache_clean_area processor.dcache_clean_area
#define cpu_set_pte_ext processor.set_pte_ext
#define cpu_do_switch_mm processor.switch_mm
-
-/* These three are private to arch/arm/kernel/suspend.c */
-#define cpu_do_suspend processor.do_suspend
-#define cpu_do_resume processor.do_resume
#endif
extern void cpu_resume(void);
diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h
index 1c0a551..b0e4e1a 100644
--- a/arch/arm/include/asm/suspend.h
+++ b/arch/arm/include/asm/suspend.h
@@ -1,7 +1,22 @@
#ifndef __ASM_ARM_SUSPEND_H
#define __ASM_ARM_SUSPEND_H
+#include <asm/memory.h>
+#include <asm/tlbflush.h>
+
extern void cpu_resume(void);
-extern int cpu_suspend(unsigned long, int (*)(unsigned long));
+
+/*
+ * Hide the first two arguments to __cpu_suspend - these are an implementation
+ * detail which platform code shouldn't have to know about.
+ */
+static inline int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+ extern int __cpu_suspend(int, long, unsigned long,
+ int (*)(unsigned long));
+ int ret = __cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, arg, fn);
+ flush_tlb_all();
+ return ret;
+}
#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 6e84750..b6f3c9f 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,7 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o
-obj-$(CONFIG_PM_SLEEP) += sleep.o suspend.o
+obj-$(CONFIG_PM_SLEEP) += sleep.o
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 3f4a517..714664b 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -8,62 +8,96 @@
.text
/*
- * Save CPU state for a suspend. This saves the CPU general purpose
- * registers, and allocates space on the kernel stack to save the CPU
- * specific registers and some other data for resume.
- * r0 = suspend function arg0
- * r1 = suspend function
+ * Save CPU state for a suspend
+ * r1 = v:p offset
+ * r2 = suspend function arg0
+ * r3 = suspend function
*/
ENTRY(__cpu_suspend)
stmfd sp!, {r4 - r11, lr}
#ifdef MULTI_CPU
ldr r10, =processor
- ldr r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
#else
- ldr r4, =cpu_suspend_size
+ ldr r5, =cpu_suspend_size
+ ldr ip, =cpu_do_resume
#endif
- mov r5, sp @ current virtual SP
- add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn
- sub sp, sp, r4 @ allocate CPU state on stack
- stmfd sp!, {r0, r1} @ save suspend func arg and pointer
- add r0, sp, #8 @ save pointer to save block
- mov r1, r4 @ size of save block
- mov r2, r5 @ virtual SP
- ldr r3, =sleep_save_sp
+ mov r6, sp @ current virtual SP
+ sub sp, sp, r5 @ allocate CPU state on stack
+ mov r0, sp @ save pointer to CPU save block
+ add ip, ip, r1 @ convert resume fn to phys
+ stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn
+ ldr r5, =sleep_save_sp
+ add r6, sp, r1 @ convert SP to phys
+ stmfd sp!, {r2, r3} @ save suspend func arg and pointer
#ifdef CONFIG_SMP
ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
ALT_UP(mov lr, #0)
and lr, lr, #15
- add r3, r3, lr, lsl #2
+ str r6, [r5, lr, lsl #2] @ save phys SP
+#else
+ str r6, [r5] @ save phys SP
+#endif
+#ifdef MULTI_CPU
+ mov lr, pc
+ ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+ bl cpu_do_suspend
+#endif
+
+ @ flush data cache
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ mov lr, pc
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ bl __cpuc_flush_kern_all
#endif
- bl __cpu_suspend_save
adr lr, BSYM(cpu_suspend_abort)
ldmfd sp!, {r0, pc} @ call suspend fn
ENDPROC(__cpu_suspend)
.ltorg
cpu_suspend_abort:
- ldmia sp!, {r1 - r3} @ pop phys pgd, virt SP, phys resume fn
- teq r0, #0
- moveq r0, #1 @ force non-zero value
+ ldmia sp!, {r1 - r3} @ pop v:p, virt SP, phys resume fn
mov sp, r2
ldmfd sp!, {r4 - r11, pc}
ENDPROC(cpu_suspend_abort)
/*
* r0 = control register value
+ * r1 = v:p offset (preserved by cpu_do_resume)
+ * r2 = phys page table base
+ * r3 = L1 section flags
*/
- .align 5
ENTRY(cpu_resume_mmu)
+#ifndef CONFIG_ARCH_HAS_SUSPEND_PAGETABLE
+ adr r4, cpu_resume_turn_mmu_on
+ mov r4, r4, lsr #20
+ orr r3, r3, r4, lsl #20
+ ldr r5, [r2, r4, lsl #2] @ save old mapping
+ str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
+ sub r2, r2, r1
+#endif
ldr r3, =cpu_resume_after_mmu
- mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc
- mrc p15, 0, r0, c0, c0, 0 @ read id reg
- mov r0, r0
- mov r0, r0
- mov pc, r3 @ jump to virtual address
+ bic r1, r0, #CR_C @ ensure D-cache is disabled
+ b cpu_resume_turn_mmu_on
ENDPROC(cpu_resume_mmu)
+ .ltorg
+ .align 5
+cpu_resume_turn_mmu_on:
+ mcr p15, 0, r1, c1, c0, 0 @ turn on MMU, I-cache, etc
+ mrc p15, 0, r1, c0, c0, 0 @ read id reg
+ mov r1, r1
+ mov r1, r1
+ mov pc, r3 @ jump to virtual address
+ENDPROC(cpu_resume_turn_mmu_on)
cpu_resume_after_mmu:
- bl cpu_init
+#ifndef CONFIG_ARCH_HAS_SUSPEND_PAGETABLE
+ str r5, [r2, r4, lsl #2] @ restore old mapping
+#endif
+ mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache
mov r0, #0 @ return zero on success
ldmfd sp!, {r4 - r11, pc}
ENDPROC(cpu_resume_after_mmu)
@@ -88,7 +122,7 @@ ENTRY(cpu_resume)
ldr r0, sleep_save_sp @ stack phys addr
#endif
setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off
- @ load phys pgd, stack, resume fn
+ @ load v:p, stack, resume fn
ARM( ldmia r0!, {r1, sp, pc} )
THUMB( ldmia r0!, {r1, r2, r3} )
THUMB( mov sp, r2 )
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
deleted file mode 100644
index 93a22d2..00000000
--- a/arch/arm/kernel/suspend.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <linux/init.h>
-
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <asm/memory.h>
-#include <asm/suspend.h>
-#include <asm/tlbflush.h>
-
-static pgd_t *suspend_pgd;
-
-extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
-extern void cpu_resume_mmu(void);
-
-/*
- * This is called by __cpu_suspend() to save the state, and do whatever
- * flushing is required to ensure that when the CPU goes to sleep we have
- * the necessary data available when the caches are not searched.
- */
-void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
-{
- *save_ptr = virt_to_phys(ptr);
-
- /* This must correspond to the LDM in cpu_resume() assembly */
- *ptr++ = virt_to_phys(suspend_pgd);
- *ptr++ = sp;
- *ptr++ = virt_to_phys(cpu_do_resume);
-
- cpu_do_suspend(ptr);
-
- flush_cache_all();
- outer_clean_range(*save_ptr, *save_ptr + ptrsz);
- outer_clean_range(virt_to_phys(save_ptr),
- virt_to_phys(save_ptr) + sizeof(*save_ptr));
-}
-
-/*
- * Hide the first two arguments to __cpu_suspend - these are an implementation
- * detail which platform code shouldn't have to know about.
- */
-int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
-{
- struct mm_struct *mm = current->active_mm;
- int ret;
-
- if (!suspend_pgd)
- return -EINVAL;
-
- /*
- * Provide a temporary page table with an identity mapping for
- * the MMU-enable code, required for resuming. On successful
- * resume (indicated by a zero return code), we need to switch
- * back to the correct page tables.
- */
- ret = __cpu_suspend(arg, fn);
- if (ret == 0) {
- cpu_switch_mm(mm->pgd, mm);
- local_flush_tlb_all();
- }
-
- return ret;
-}
-
-static int __init cpu_suspend_init(void)
-{
- suspend_pgd = pgd_alloc(&init_mm);
- if (suspend_pgd) {
- unsigned long addr = virt_to_phys(cpu_resume_mmu);
- identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE);
- }
- return suspend_pgd ? 0 : -ENOMEM;
-}
-core_initcall(cpu_suspend_init);
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 90d66a1..1aa448c 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -21,6 +21,8 @@ config ARCH_TEGRA_2x_SOC
select ARCH_SUPPORTS_MSI if TEGRA_PCI
select PCI_MSI if TEGRA_PCI
select CPA
+ select ARM_ERRATA_716044
+ select ARCH_HAS_SUSPEND_PAGETABLE
help
Support for NVIDIA Tegra AP20 and T20 processors, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -46,6 +48,7 @@ config ARCH_TEGRA_3x_SOC
select ARM_ERRATA_754322
select TEGRA_LP2_ARM_TWD if HAVE_ARM_TWD && !TEGRA_RAIL_OFF_MULTIPLE_CPUS
select CPA
+ select ARCH_HAS_SUSPEND_PAGETABLE
help
Support for NVIDIA Tegra 3 family of SoCs, based upon the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -294,14 +297,6 @@ config TEGRA_IOVMM_SMMU
space through the SMMU (System Memory Management Unit)
hardware included on Tegra SoCs.
-config TEGRA_SMMU_BASE_AT_E0000000
- bool "Force SMMU IOVA base to 0xe0000000"
- depends on TEGRA_IOVMM_SMMU
- default n
- help
- Forces SMMU IOVA base address to 0xe0000000 for debug purposes
- only. Select n for production systems.
-
config TEGRA_IOVMM_SMMU_SYSFS
bool "Enable SMMU register access for debugging"
depends on TEGRA_IOVMM_SMMU
@@ -333,6 +328,7 @@ config TEGRA_THERMAL_THROTTLE
bool "Enable throttling of CPU speed on overtemp"
depends on TEGRA_SILICON_PLATFORM
depends on CPU_FREQ
+ depends on THERMAL
default y
help
Also requires enabling a temperature sensor such as NCT1008.
@@ -453,11 +449,6 @@ config TEGRA_BB_XMM_POWER2
insert this LKM to initiate 2nd USB enumeration power sequence
- after modem software has been downloaded to flashless device.
-config TEGRA_THERMAL_SYSFS
- bool "Enable Thermal driver to use Thermal Sysfs infrastructure"
- depends on THERMAL
- default y
-
config TEGRA_PLLM_RESTRICTED
bool "Restrict PLLM usage as module clock source"
depends on !ARCH_TEGRA_2x_SOC
@@ -494,4 +485,10 @@ config TEGRA_PREINIT_CLOCKS
help
Preinitialize Tegra clocks to known states before actual full-
scale clock initialization starts.
+
+config TEGRA_PREPOWER_WIFI
+ bool "Pre-power up WiFi "
+ default n
+ help
+ Pre-power up the on board WiFi chip
endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 21d43a7..6b1c4c5 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += common-t2.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += common-t3.o
obj-y += io.o
obj-y += irq.o
-obj-$(CONFIG_TEGRA_GRHOST) += syncpt.o
obj-y += clock.o
obj-y += clock-common.o
obj-y += timer.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index e227331..5f39449 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -30,7 +30,7 @@
static DEFINE_MUTEX(tegra_apb_dma_lock);
-#ifdef CONFIG_TEGRA_SYSTEM_DMA
+#if defined(CONFIG_TEGRA_SYSTEM_DMA) && defined(CONFIG_ARCH_TEGRA_2x_SOC)
static struct tegra_dma_channel *tegra_apb_dma;
static u32 *tegra_apb_bb;
static dma_addr_t tegra_apb_bb_phys;
@@ -68,6 +68,8 @@ static inline u32 apb_readl(unsigned long offset)
req.source_wrap = 4;
req.req_sel = 0;
req.size = 4;
+ dma_sync_single_for_device(NULL, tegra_apb_bb_phys,
+ sizeof(u32), DMA_FROM_DEVICE);
INIT_COMPLETION(tegra_apb_wait);
@@ -81,6 +83,8 @@ static inline u32 apb_readl(unsigned long offset)
*(u32 *)tegra_apb_bb = 0;
}
+ dma_sync_single_for_cpu(NULL, tegra_apb_bb_phys,
+ sizeof(u32), DMA_FROM_DEVICE);
mutex_unlock(&tegra_apb_dma_lock);
return *((u32 *)tegra_apb_bb);
}
@@ -97,6 +101,8 @@ static inline void apb_writel(u32 value, unsigned long offset)
}
mutex_lock(&tegra_apb_dma_lock);
+ dma_sync_single_for_cpu(NULL, tegra_apb_bb_phys,
+ sizeof(u32), DMA_TO_DEVICE);
*((u32 *)tegra_apb_bb) = value;
req.complete = apb_dma_complete;
req.to_memory = 0;
@@ -111,6 +117,8 @@ static inline void apb_writel(u32 value, unsigned long offset)
INIT_COMPLETION(tegra_apb_wait);
+ dma_sync_single_for_device(NULL, tegra_apb_bb_phys,
+ sizeof(u32), DMA_TO_DEVICE);
tegra_dma_enqueue_req(tegra_apb_dma, &req);
ret = wait_for_completion_timeout(&tegra_apb_wait,
@@ -121,17 +129,6 @@ static inline void apb_writel(u32 value, unsigned long offset)
mutex_unlock(&tegra_apb_dma_lock);
}
-#else
-static inline u32 apb_readl(unsigned long offset)
-{
- return readl(IO_TO_VIRT(offset));
-}
-
-static inline void apb_writel(u32 value, unsigned long offset)
-{
- writel(value, IO_TO_VIRT(offset));
-}
-#endif
u32 tegra_apb_readl(unsigned long offset)
{
@@ -142,10 +139,11 @@ void tegra_apb_writel(u32 value, unsigned long offset)
{
apb_writel(value, offset);
}
+#endif
static int tegra_init_apb_dma(void)
{
-#ifdef CONFIG_TEGRA_SYSTEM_DMA
+#if defined(CONFIG_TEGRA_SYSTEM_DMA) && defined(CONFIG_ARCH_TEGRA_2x_SOC)
tegra_apb_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT |
TEGRA_DMA_SHARED, "apbio");
if (!tegra_apb_dma) {
diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h
index f0c87f0..121fda3 100644
--- a/arch/arm/mach-tegra/apbio.h
+++ b/arch/arm/mach-tegra/apbio.h
@@ -15,5 +15,17 @@
*
*/
+#if defined(CONFIG_TEGRA_SYSTEM_DMA) && defined(CONFIG_ARCH_TEGRA_2x_SOC)
u32 tegra_apb_readl(unsigned long offset);
void tegra_apb_writel(u32 value, unsigned long offset);
+#else
+static inline u32 tegra_apb_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(offset));
+}
+
+static inline void tegra_apb_writel(u32 value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(offset));
+}
+#endif
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.c b/arch/arm/mach-tegra/baseband-xmm-power.c
index 7d5c527..20f8d30 100644
--- a/arch/arm/mach-tegra/baseband-xmm-power.c
+++ b/arch/arm/mach-tegra/baseband-xmm-power.c
@@ -30,8 +30,11 @@
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/pm_runtime.h>
+#include <linux/suspend.h>
+#include <linux/pm_qos_params.h>
#include <mach/usb_phy.h>
#include "board.h"
+#include "board-enterprise.h"
#include "devices.h"
#include "gpio-names.h"
#include "baseband-xmm-power.h"
@@ -87,12 +90,12 @@ static enum {
IPC_AP_WAKE_H,
} ipc_ap_wake_state;
-enum baseband_xmm_powerstate_t baseband_xmm_powerstate;
+static enum baseband_xmm_powerstate_t baseband_xmm_powerstate;
static struct workqueue_struct *workqueue;
static struct work_struct init1_work;
static struct work_struct init2_work;
static struct work_struct L2_resume_work;
-static struct baseband_power_platform_data *baseband_power_driver_data;
+static struct work_struct autopm_resume_work;
static bool register_hsic_device;
static struct wake_lock wakelock;
static struct usb_device *usbdev;
@@ -100,64 +103,133 @@ static bool CP_initiated_L2toL0;
static bool modem_power_on;
static int power_onoff;
static int reenable_autosuspend;
-static struct work_struct autopm_resume_work;
static bool wakeup_pending;
static bool modem_sleep_flag;
static spinlock_t xmm_lock;
static DEFINE_MUTEX(xmm_onoff_mutex);
+static bool system_suspending;
+static struct regulator *enterprise_hsic_reg;
+static bool _hsic_reg_status;
+static struct pm_qos_request_list boost_cpu_freq_req;
+static struct delayed_work pm_qos_work;
+#define BOOST_CPU_FREQ_MIN 1500000
+
+/* driver specific data - same structure is used for flashless
+ * & flashed modem drivers i.e. baseband-xmm-power2.c
+ */
+struct xmm_power_data xmm_power_drv_data;
+EXPORT_SYMBOL(xmm_power_drv_data);
-static void baseband_xmm_power_L2_resume(void);
-static int baseband_xmm_power_driver_handle_resume(
+static void xmm_power_L2_resume(void);
+static int xmm_power_driver_handle_resume(
struct baseband_power_platform_data *data);
+static int tegra_baseband_rail_on(void)
+{
+ int ret;
+ struct board_info bi;
+ tegra_get_board_info(&bi);
+
+ /* only applicable to enterprise */
+ if (bi.board_id != BOARD_E1197)
+ return 0;
+
+ if (_hsic_reg_status == true)
+ return 0;
+
+ if (enterprise_hsic_reg == NULL) {
+ enterprise_hsic_reg = regulator_get(NULL, "avdd_hsic");
+ if (IS_ERR_OR_NULL(enterprise_hsic_reg)) {
+ pr_err("xmm: could not get regulator vddio_hsic\n");
+ enterprise_hsic_reg = NULL;
+ return PTR_ERR(enterprise_hsic_reg);
+ }
+ }
+ ret = regulator_enable(enterprise_hsic_reg);
+ if (ret < 0) {
+ pr_err("xmm: failed to enable regulator\n");
+ return ret;
+ }
+ _hsic_reg_status = true;
+ return 0;
+}
+
+static int tegra_baseband_rail_off(void)
+{
+ int ret;
+ struct board_info bi;
+ tegra_get_board_info(&bi);
+
+ /* only applicable to enterprise */
+ if (bi.board_id != BOARD_E1197)
+ return 0;
+
+ if (_hsic_reg_status == false)
+ return 0;
+
+ if (IS_ERR_OR_NULL(enterprise_hsic_reg)) {
+ pr_err("xmm: unbalanced disable on vddio_hsic regulator\n");
+ enterprise_hsic_reg = NULL;
+ return PTR_ERR(enterprise_hsic_reg);
+ }
+ ret = regulator_disable(enterprise_hsic_reg);
+ if (ret < 0) {
+ pr_err("xmm: failed to disable regulator\n");
+ return ret;
+ }
+ _hsic_reg_status = false;
+ return 0;
+}
+
static int baseband_modem_power_on(struct baseband_power_platform_data *data)
{
/* set IPC_HSIC_ACTIVE active */
- gpio_set_value(baseband_power_driver_data->
- modem.xmm.ipc_hsic_active, 1);
-
- /* wait 20 ms */
- mdelay(20);
+ gpio_set_value(data->modem.xmm.ipc_hsic_active, 1);
/* reset / power on sequence */
- mdelay(40);
+ msleep(40);
gpio_set_value(data->modem.xmm.bb_rst, 1);
mdelay(1);
gpio_set_value(data->modem.xmm.bb_on, 1);
- udelay(40);
+ udelay(70);
gpio_set_value(data->modem.xmm.bb_on, 0);
+ pr_debug("%s: pm qos request CPU 1.5GHz\n", __func__);
+ pm_qos_update_request(&boost_cpu_freq_req, (s32)BOOST_CPU_FREQ_MIN);
+ /* Device enumeration should happen in 1 sec however in any case
+ * we want to request it back to normal so schedule work to restore
+ * CPU freq after 2 seconds */
+ schedule_delayed_work(&pm_qos_work, msecs_to_jiffies(2000));
+
return 0;
}
-static int baseband_xmm_power_on(struct platform_device *device)
+static int xmm_power_on(struct platform_device *device)
{
- struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *)
+ struct baseband_power_platform_data *pdata =
device->dev.platform_data;
+ struct xmm_power_data *data = &xmm_power_drv_data;
int ret;
pr_debug("%s {\n", __func__);
/* check for platform data */
- if (!data) {
- pr_err("%s: !data\n", __func__);
+ if (!pdata) {
+ pr_err("%s: !pdata\n", __func__);
return -EINVAL;
}
if (baseband_xmm_powerstate != BBXMM_PS_UNINIT)
return -EINVAL;
+ tegra_baseband_rail_on();
+
/* reset the state machine */
baseband_xmm_powerstate = BBXMM_PS_INIT;
modem_sleep_flag = false;
+ ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
- if (modem_ver < XMM_MODEM_VER_1130)
- ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
- else
- ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
-
- pr_debug("%s wake_st(%d) modem version %d\n", __func__,
- ipc_ap_wake_state, modem_ver);
+ pr_debug("%s wake_st(%d) modem version %lu\n", __func__,
+ ipc_ap_wake_state, modem_ver);
/* register usb host controller */
if (!modem_flash) {
@@ -167,35 +239,35 @@ static int baseband_xmm_power_on(struct platform_device *device)
pr_debug("%s: register usb host controller\n",
__func__);
modem_power_on = true;
- if (data->hsic_register)
- data->modem.xmm.hsic_device =
- data->hsic_register();
+ if (pdata->hsic_register)
+ data->hsic_device = pdata->hsic_register();
else
pr_err("%s: hsic_register is missing\n",
__func__);
register_hsic_device = false;
} else {
/* register usb host controller */
- if (data->hsic_register)
- data->modem.xmm.hsic_device =
- data->hsic_register();
+ if (pdata->hsic_register)
+ data->hsic_device = pdata->hsic_register();
/* turn on modem */
pr_debug("%s call baseband_modem_power_on\n", __func__);
- baseband_modem_power_on(data);
+ baseband_modem_power_on(pdata);
}
}
- ret = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
+ ret = enable_irq_wake(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
if (ret < 0)
pr_err("%s: enable_irq_wake error\n", __func__);
-
pr_debug("%s }\n", __func__);
return 0;
}
-static int baseband_xmm_power_off(struct platform_device *device)
+static int xmm_power_off(struct platform_device *device)
{
- struct baseband_power_platform_data *data;
+ struct baseband_power_platform_data *pdata =
+ device->dev.platform_data;
+ struct xmm_power_data *data = &xmm_power_drv_data;
+
int ret;
unsigned long flags;
@@ -208,51 +280,51 @@ static int baseband_xmm_power_off(struct platform_device *device)
pr_err("%s: !device\n", __func__);
return -EINVAL;
}
- data = (struct baseband_power_platform_data *)
- device->dev.platform_data;
- if (!data) {
- pr_err("%s: !data\n", __func__);
+ if (!pdata) {
+ pr_err("%s: !pdata\n", __func__);
return -EINVAL;
}
ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
- ret = disable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
+ ret = disable_irq_wake(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
if (ret < 0)
pr_err("%s: disable_irq_wake error\n", __func__);
/* unregister usb host controller */
- if (data->hsic_unregister)
- data->hsic_unregister(data->modem.xmm.hsic_device);
+ if (pdata->hsic_unregister)
+ pdata->hsic_unregister(data->hsic_device);
else
pr_err("%s: hsic_unregister is missing\n", __func__);
/* set IPC_HSIC_ACTIVE low */
- gpio_set_value(baseband_power_driver_data->
- modem.xmm.ipc_hsic_active, 0);
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
/* wait 20 ms */
mdelay(20);
/* drive bb_rst low */
- gpio_set_value(data->modem.xmm.bb_rst, 0);
+ gpio_set_value(pdata->modem.xmm.bb_rst, 0);
mdelay(1);
- spin_lock_irqsave(&xmm_lock, flags);
baseband_xmm_powerstate = BBXMM_PS_UNINIT;
- wakeup_pending = false;
modem_sleep_flag = false;
+ CP_initiated_L2toL0 = false;
+ spin_lock_irqsave(&xmm_lock, flags);
+ wakeup_pending = false;
+ system_suspending = false;
spin_unlock_irqrestore(&xmm_lock, flags);
/* start registration process once again on xmm on */
register_hsic_device = true;
+
+ tegra_baseband_rail_off();
pr_debug("%s }\n", __func__);
return 0;
}
-static ssize_t baseband_xmm_onoff(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t xmm_onoff(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
int pwr;
int size;
@@ -288,38 +360,46 @@ static ssize_t baseband_xmm_onoff(struct device *dev,
pr_debug("%s power_onoff=%d\n", __func__, power_onoff);
if (power_onoff == 0)
- baseband_xmm_power_off(device);
+ xmm_power_off(device);
else if (power_onoff == 1)
- baseband_xmm_power_on(device);
+ xmm_power_on(device);
mutex_unlock(&xmm_onoff_mutex);
return count;
}
+static void pm_qos_worker(struct work_struct *work)
+{
+ pr_debug("%s - pm qos CPU back to normal\n", __func__);
+ pm_qos_update_request(&boost_cpu_freq_req,
+ (s32)PM_QOS_CPU_FREQ_MIN_DEFAULT_VALUE);
+}
+
static DEVICE_ATTR(xmm_onoff, S_IRUSR | S_IWUSR | S_IRGRP,
- NULL, baseband_xmm_onoff);
+ NULL, xmm_onoff);
void baseband_xmm_set_power_status(unsigned int status)
{
- struct baseband_power_platform_data *data = baseband_power_driver_data;
+ struct baseband_power_platform_data *data = xmm_power_drv_data.pdata;
int value = 0;
unsigned long flags;
- pr_debug("%s\n", __func__);
-
if (baseband_xmm_powerstate == status)
return;
-
+ pr_debug("%s\n", __func__);
switch (status) {
case BBXMM_PS_L0:
if (modem_sleep_flag) {
pr_info("%s Resume from L3 without calling resume"
"function\n", __func__);
- baseband_xmm_power_driver_handle_resume(data);
+ xmm_power_driver_handle_resume(data);
}
pr_info("L0\n");
+ baseband_xmm_powerstate = status;
+ if (!wake_lock_active(&wakelock))
+ wake_lock(&wakelock);
value = gpio_get_value(data->modem.xmm.ipc_hsic_active);
pr_debug("before L0 ipc_hsic_active=%d\n", value);
if (!value) {
@@ -330,16 +410,21 @@ void baseband_xmm_set_power_status(unsigned int status)
modem_power_on = false;
baseband_modem_power_on(data);
}
-
- if (!wake_lock_active(&wakelock))
- wake_lock(&wakelock);
-
pr_debug("gpio host active high->\n");
break;
case BBXMM_PS_L2:
pr_info("L2\n");
- wake_unlock(&wakelock);
- modem_sleep_flag = true;
+ baseband_xmm_powerstate = status;
+ spin_lock_irqsave(&xmm_lock, flags);
+ if (wakeup_pending) {
+ spin_unlock_irqrestore(&xmm_lock, flags);
+ xmm_power_L2_resume();
+ } else {
+ spin_unlock_irqrestore(&xmm_lock, flags);
+ if (wake_lock_active(&wakelock))
+ wake_unlock(&wakelock);
+ modem_sleep_flag = true;
+ }
break;
case BBXMM_PS_L3:
if (baseband_xmm_powerstate == BBXMM_PS_L2TOL0) {
@@ -352,6 +437,14 @@ void baseband_xmm_set_power_status(unsigned int status)
}
}
pr_info("L3\n");
+ /* system is going to suspend */
+ if (baseband_xmm_powerstate == BBXMM_PS_L2)
+ tegra_baseband_rail_off();
+
+ baseband_xmm_powerstate = status;
+ spin_lock_irqsave(&xmm_lock, flags);
+ system_suspending = false;
+ spin_unlock_irqrestore(&xmm_lock, flags);
if (wake_lock_active(&wakelock)) {
pr_info("%s: releasing wakelock before L3\n",
__func__);
@@ -361,140 +454,138 @@ void baseband_xmm_set_power_status(unsigned int status)
pr_debug("gpio host active low->\n");
break;
case BBXMM_PS_L2TOL0:
+ spin_lock_irqsave(&xmm_lock, flags);
+ system_suspending = false;
+ wakeup_pending = false;
+ spin_unlock_irqrestore(&xmm_lock, flags);
/* do this only from L2 state */
if (baseband_xmm_powerstate == BBXMM_PS_L2) {
baseband_xmm_powerstate = status;
pr_debug("BB XMM POWER STATE = %d\n", status);
- baseband_xmm_power_L2_resume();
+ xmm_power_L2_resume();
}
+ baseband_xmm_powerstate = status;
+ break;
+ case BBXMM_PS_L3TOL0:
+ /* poweron rail for L3 -> L0 (system resume) */
+ pr_debug("L3 -> L0, turning on power rail.\n");
+ tegra_baseband_rail_on();
+ baseband_xmm_powerstate = status;
+ break;
default:
+ baseband_xmm_powerstate = status;
break;
}
- baseband_xmm_powerstate = status;
pr_debug("BB XMM POWER STATE = %d\n", status);
}
EXPORT_SYMBOL_GPL(baseband_xmm_set_power_status);
-irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
+irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
{
+ struct baseband_power_platform_data *data = xmm_power_drv_data.pdata;
int value;
- value = gpio_get_value(baseband_power_driver_data->
- modem.xmm.ipc_ap_wake);
-
+ value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
pr_debug("%s g(%d), wake_st(%d)\n", __func__, value, ipc_ap_wake_state);
- if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
+ /* modem initialization/bootup part*/
+ if (unlikely(ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY)) {
pr_err("%s - spurious irq\n", __func__);
+ return IRQ_HANDLED;
} else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
if (!value) {
pr_debug("%s - IPC_AP_WAKE_INIT1"
- " - got falling edge\n",
- __func__);
+ " - got falling edge\n", __func__);
/* go to IPC_AP_WAKE_INIT1 state */
ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
- /* queue work */
queue_work(workqueue, &init1_work);
- } else {
+ } else
pr_debug("%s - IPC_AP_WAKE_INIT1"
- " - wait for falling edge\n",
- __func__);
- }
+ " - wait for falling edge\n", __func__);
+ return IRQ_HANDLED;
} else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
if (!value) {
pr_debug("%s - IPC_AP_WAKE_INIT2"
- " - wait for rising edge\n",
- __func__);
+ " - wait for rising edge\n", __func__);
} else {
pr_debug("%s - IPC_AP_WAKE_INIT2"
- " - got rising edge\n",
- __func__);
+ " - got rising edge\n", __func__);
/* go to IPC_AP_WAKE_INIT2 state */
ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
- /* queue work */
queue_work(workqueue, &init2_work);
}
- } else {
- if (!value) {
- pr_debug("%s - falling\n", __func__);
- /* [ver < 1130] gpio protocol falling edge */
- if (modem_ver < XMM_MODEM_VER_1130) {
- pr_debug("gpio host wakeup done <-\n");
- value = gpio_get_value
- (baseband_power_driver_data->
- modem.xmm.ipc_bb_wake);
- if (value) {
- /* Clear the slave wakeup request */
- gpio_set_value
- (baseband_power_driver_data->
- modem.xmm.ipc_bb_wake, 0);
- pr_debug("gpio slave wakeup done ->\n");
- }
- }
- /* [ver >= 1130] gpio protocol falling edge */
- if (modem_ver >= XMM_MODEM_VER_1130) {
- if (baseband_xmm_powerstate == BBXMM_PS_L2) {
- CP_initiated_L2toL0 = true;
- baseband_xmm_set_power_status
- (BBXMM_PS_L2TOL0);
- } else if (baseband_xmm_powerstate ==
- BBXMM_PS_L3) {
- spin_lock(&xmm_lock);
- wakeup_pending = true;
- spin_unlock(&xmm_lock);
- pr_info("CP L3 -> L0\n");
- }
- }
- /* save gpio state */
+ return IRQ_HANDLED;
+ }
+
+ /* modem wakeup part */
+ if (!value) {
+ pr_debug("%s - falling\n", __func__);
+ /* First check it a CP ack or CP wake */
+ value = gpio_get_value(data->modem.xmm.ipc_bb_wake);
+ if (value) {
+ pr_debug("cp ack for bb_wake\n");
ipc_ap_wake_state = IPC_AP_WAKE_L;
+ return IRQ_HANDLED;
+ }
+ spin_lock(&xmm_lock);
+ wakeup_pending = true;
+ if (system_suspending) {
+ spin_unlock(&xmm_lock);
+ pr_info("Set wakeup_pending = 1 in system_"
+ " suspending!!!\n");
} else {
- pr_debug("%s - rising\n", __func__);
- /* [ver >= 1130] gpio protocol rising edge */
- if (modem_ver >= XMM_MODEM_VER_1130) {
- pr_debug("gpio host wakeup done <-\n");
- value = gpio_get_value
- (baseband_power_driver_data->
- modem.xmm.ipc_bb_wake);
- if (value) {
- /* Clear the slave wakeup request */
- gpio_set_value
- (baseband_power_driver_data->
- modem.xmm.ipc_bb_wake, 0);
- pr_debug("gpio slave wakeup done ->\n");
- if (reenable_autosuspend && usbdev) {
- reenable_autosuspend = false;
- queue_work(workqueue,
- &autopm_resume_work);
- }
- }
- if ((baseband_xmm_powerstate ==
- BBXMM_PS_L2TOL0) ||
- (baseband_xmm_powerstate ==
- BBXMM_PS_L3TOL0))
- baseband_xmm_set_power_status(
- BBXMM_PS_L0);
- else
- pr_info("%s:no state"
- "change required\n", __func__);
+ if ((baseband_xmm_powerstate == BBXMM_PS_L3) ||
+ (baseband_xmm_powerstate == BBXMM_PS_L3TOL0)) {
+ spin_unlock(&xmm_lock);
+ pr_info(" CP L3 -> L0\n");
+ } else if (baseband_xmm_powerstate == BBXMM_PS_L2) {
+ CP_initiated_L2toL0 = true;
+ spin_unlock(&xmm_lock);
+ baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
+ } else {
+ CP_initiated_L2toL0 = true;
+ spin_unlock(&xmm_lock);
}
- /* save gpio state */
+ }
+ /* save gpio state */
+ ipc_ap_wake_state = IPC_AP_WAKE_L;
+ } else {
+ pr_debug("%s - rising\n", __func__);
+ value = gpio_get_value(data->modem.xmm.ipc_hsic_active);
+ if (!value) {
+ pr_info("host active low: ignore request\n");
ipc_ap_wake_state = IPC_AP_WAKE_H;
+ return IRQ_HANDLED;
}
+ value = gpio_get_value(data->modem.xmm.ipc_bb_wake);
+ if (value) {
+ /* Clear the slave wakeup request */
+ gpio_set_value(data->modem.xmm.ipc_bb_wake, 0);
+ pr_debug("gpio slave wakeup done ->\n");
+ }
+ if (reenable_autosuspend && usbdev) {
+ reenable_autosuspend = false;
+ queue_work(workqueue, &autopm_resume_work);
+ }
+ modem_sleep_flag = false;
+ baseband_xmm_set_power_status(BBXMM_PS_L0);
+ /* save gpio state */
+ ipc_ap_wake_state = IPC_AP_WAKE_H;
}
return IRQ_HANDLED;
}
-EXPORT_SYMBOL(baseband_xmm_power_ipc_ap_wake_irq);
+EXPORT_SYMBOL(xmm_power_ipc_ap_wake_irq);
-static void baseband_xmm_power_init1_work(struct work_struct *work)
+static void xmm_power_init1_work(struct work_struct *work)
{
+ struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
int value;
pr_debug("%s {\n", __func__);
/* check if IPC_HSIC_ACTIVE high */
- value = gpio_get_value(baseband_power_driver_data->
- modem.xmm.ipc_hsic_active);
+ value = gpio_get_value(pdata->modem.xmm.ipc_hsic_active);
if (value != 1) {
pr_err("%s - expected IPC_HSIC_ACTIVE high!\n", __func__);
return;
@@ -504,15 +595,13 @@ static void baseband_xmm_power_init1_work(struct work_struct *work)
mdelay(100);
/* set IPC_HSIC_ACTIVE low */
- gpio_set_value(baseband_power_driver_data->
- modem.xmm.ipc_hsic_active, 0);
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
/* wait 10 ms */
mdelay(10);
/* set IPC_HSIC_ACTIVE high */
- gpio_set_value(baseband_power_driver_data->
- modem.xmm.ipc_hsic_active, 1);
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 1);
/* wait 20 ms */
mdelay(20);
@@ -520,20 +609,20 @@ static void baseband_xmm_power_init1_work(struct work_struct *work)
pr_debug("%s }\n", __func__);
}
-static void baseband_xmm_power_init2_work(struct work_struct *work)
+static void xmm_power_init2_work(struct work_struct *work)
{
- struct baseband_power_platform_data *data = baseband_power_driver_data;
+ struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
pr_debug("%s\n", __func__);
/* check input */
- if (!data)
+ if (!pdata)
return;
/* register usb host controller only once */
if (register_hsic_device) {
- if (data->hsic_register)
- data->modem.xmm.hsic_device = data->hsic_register();
+ if (pdata->hsic_register)
+ xmm_power_drv_data.hsic_device = pdata->hsic_register();
else
pr_err("%s: hsic_register is missing\n", __func__);
register_hsic_device = false;
@@ -541,7 +630,7 @@ static void baseband_xmm_power_init2_work(struct work_struct *work)
}
-static void baseband_xmm_power_autopm_resume(struct work_struct *work)
+static void xmm_power_autopm_resume(struct work_struct *work)
{
struct usb_interface *intf;
@@ -549,26 +638,37 @@ static void baseband_xmm_power_autopm_resume(struct work_struct *work)
if (usbdev) {
usb_lock_device(usbdev);
intf = usb_ifnum_to_if(usbdev, 0);
- usb_autopm_get_interface(intf);
- usb_autopm_put_interface(intf);
+ if (!intf) {
+ usb_unlock_device(usbdev);
+ return;
+ }
+ if (usb_autopm_get_interface(intf) == 0)
+ usb_autopm_put_interface(intf);
usb_unlock_device(usbdev);
}
}
/* Do the work for AP/CP initiated L2->L0 */
-static void baseband_xmm_power_L2_resume(void)
+static void xmm_power_L2_resume(void)
{
- struct baseband_power_platform_data *data = baseband_power_driver_data;
+ struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
int value;
- int delay = 1000; /* maxmum delay in msec */
+ int delay = 10000; /* maxmum delay in msec */
+ unsigned long flags;
pr_debug("%s\n", __func__);
- if (!baseband_power_driver_data)
+ if (!pdata)
return;
+ /* claim the wakelock here to avoid any system suspend */
+ if (!wake_lock_active(&wakelock))
+ wake_lock(&wakelock);
modem_sleep_flag = false;
+ spin_lock_irqsave(&xmm_lock, flags);
+ wakeup_pending = false;
+ spin_unlock_irqrestore(&xmm_lock, flags);
if (CP_initiated_L2toL0) {
pr_info("CP L2->L0\n");
@@ -577,22 +677,29 @@ static void baseband_xmm_power_L2_resume(void)
} else {
/* set the slave wakeup request */
pr_info("AP L2->L0\n");
- gpio_set_value(data->modem.xmm.ipc_bb_wake, 1);
- pr_debug("waiting for host wakeup from CP...\n");
- do {
- mdelay(1);
- value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
- delay--;
- } while ((value) && (delay));
- if (delay)
- pr_debug("gpio host wakeup low <-\n");
- else
- pr_info("!!AP L2->L0 Failed\n");
+ value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
+ if (value) {
+ pr_debug("waiting for host wakeup from CP...\n");
+ /* wake bb */
+ gpio_set_value(pdata->modem.xmm.ipc_bb_wake, 1);
+ do {
+ mdelay(1);
+ value = gpio_get_value(
+ pdata->modem.xmm.ipc_ap_wake);
+ delay--;
+ } while ((value) && (delay));
+ if (delay)
+ pr_debug("gpio host wakeup low <-\n");
+ else
+ pr_info("!!AP L2->L0 Failed\n");
+ } else {
+ pr_info("CP already ready\n");
+ }
}
}
/* Do the work for CP initiated L2->L0 */
-static void baseband_xmm_power_L2_resume_work(struct work_struct *work)
+static void xmm_power_L2_resume_work(struct work_struct *work)
{
struct usb_interface *intf;
@@ -609,119 +716,77 @@ static void baseband_xmm_power_L2_resume_work(struct work_struct *work)
pr_debug("} %s\n", __func__);
}
-static void baseband_xmm_power_reset_on(void)
+static void xmm_power_reset_on(struct baseband_power_platform_data *pdata)
{
/* reset / power on sequence */
- mdelay(40);
- gpio_set_value(baseband_power_driver_data->modem.xmm.bb_rst, 1);
+ gpio_set_value(pdata->modem.xmm.bb_rst, 0);
+ msleep(40);
+ gpio_set_value(pdata->modem.xmm.bb_rst, 1);
mdelay(1);
- gpio_set_value(baseband_power_driver_data->modem.xmm.bb_on, 1);
- udelay(40);
- gpio_set_value(baseband_power_driver_data->modem.xmm.bb_on, 0);
+ gpio_set_value(pdata->modem.xmm.bb_on, 1);
+ udelay(70);
+ gpio_set_value(pdata->modem.xmm.bb_on, 0);
}
-static struct baseband_xmm_power_work_t *baseband_xmm_power_work;
-static void baseband_xmm_power_work_func(struct work_struct *work)
+static void xmm_power_work_func(struct work_struct *work)
{
- struct baseband_xmm_power_work_t *bbxmm_work
- = (struct baseband_xmm_power_work_t *) work;
+ struct xmm_power_data *data =
+ container_of(work, struct xmm_power_data, work);
+ struct baseband_power_platform_data *pdata = data->pdata;
pr_debug("%s\n", __func__);
- switch (bbxmm_work->state) {
+ switch (data->state) {
case BBXMM_WORK_UNINIT:
pr_debug("BBXMM_WORK_UNINIT\n");
break;
case BBXMM_WORK_INIT:
pr_debug("BBXMM_WORK_INIT\n");
/* go to next state */
- bbxmm_work->state = (modem_flash && !modem_pm)
+ data->state = (modem_flash && !modem_pm)
? BBXMM_WORK_INIT_FLASH_STEP1
: (modem_flash && modem_pm)
? BBXMM_WORK_INIT_FLASH_PM_STEP1
: (!modem_flash && modem_pm)
? BBXMM_WORK_INIT_FLASHLESS_PM_STEP1
: BBXMM_WORK_UNINIT;
- pr_debug("Go to next state %d\n", bbxmm_work->state);
+ pr_debug("Go to next state %d\n", data->state);
queue_work(workqueue, work);
break;
case BBXMM_WORK_INIT_FLASH_STEP1:
pr_debug("BBXMM_WORK_INIT_FLASH_STEP1\n");
/* register usb host controller */
pr_debug("%s: register usb host controller\n", __func__);
- if (baseband_power_driver_data->hsic_register)
- baseband_power_driver_data->modem.xmm.hsic_device =
- baseband_power_driver_data->hsic_register();
+ if (pdata->hsic_register)
+ data->hsic_device = pdata->hsic_register();
else
pr_err("%s: hsic_register is missing\n", __func__);
break;
case BBXMM_WORK_INIT_FLASH_PM_STEP1:
pr_debug("BBXMM_WORK_INIT_FLASH_PM_STEP1\n");
- /* [modem ver >= 1130] start with IPC_HSIC_ACTIVE low */
- if (modem_ver >= XMM_MODEM_VER_1130) {
- pr_debug("%s: ver > 1130:"
- " ipc_hsic_active -> 0\n", __func__);
- gpio_set_value(baseband_power_driver_data->
- modem.xmm.ipc_hsic_active, 0);
- }
+ pr_debug("%s: ipc_hsic_active -> 0\n", __func__);
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 1);
/* reset / power on sequence */
- baseband_xmm_power_reset_on();
+ xmm_power_reset_on(pdata);
/* set power status as on */
power_onoff = 1;
- /* optional delay
- * 0 = flashless
- * ==> causes next step to enumerate modem boot rom
- * (058b / 0041)
- * some delay > boot rom timeout
- * ==> causes next step to enumerate modem software
- * (1519 / 0020)
- * (requires modem to be flash version, not flashless
- * version)
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
+
+ /* expecting init2 performs register hsic to enumerate modem
+ * software directly.
*/
- if (enum_delay_ms)
- mdelay(enum_delay_ms);
- /* register usb host controller */
- pr_debug("%s: register usb host controller\n", __func__);
- if (baseband_power_driver_data->hsic_register)
- baseband_power_driver_data->modem.xmm.hsic_device =
- baseband_power_driver_data->hsic_register();
- else
- pr_err("%s: hsic_register is missing\n", __func__);
- /* go to next state */
- bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
- ? BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1
- : BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1;
- queue_work(workqueue, work);
- pr_debug("Go to next state %d\n", bbxmm_work->state);
- break;
- case BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1:
- pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1\n");
- break;
- case BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1:
- pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1\n");
break;
case BBXMM_WORK_INIT_FLASHLESS_PM_STEP1:
pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP1\n");
- /* go to next state */
- bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
- ? BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ
- : BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
- queue_work(workqueue, work);
- break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1\n");
- break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1\n");
+ pr_info("%s: flashless is not supported here\n", __func__);
break;
default:
break;
}
-
}
-static void baseband_xmm_device_add_handler(struct usb_device *udev)
+static void xmm_device_add_handler(struct usb_device *udev)
{
struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
const struct usb_device_id *id;
@@ -741,7 +806,7 @@ static void baseband_xmm_device_add_handler(struct usb_device *udev)
}
}
-static void baseband_xmm_device_remove_handler(struct usb_device *udev)
+static void xmm_device_remove_handler(struct usb_device *udev)
{
if (usbdev == udev) {
pr_info("Remove device %d <%s %s>\n", udev->devnum,
@@ -756,10 +821,10 @@ static int usb_xmm_notify(struct notifier_block *self, unsigned long action,
{
switch (action) {
case USB_DEVICE_ADD:
- baseband_xmm_device_add_handler(blob);
+ xmm_device_add_handler(blob);
break;
case USB_DEVICE_REMOVE:
- baseband_xmm_device_remove_handler(blob);
+ xmm_device_remove_handler(blob);
break;
}
@@ -771,11 +836,64 @@ static struct notifier_block usb_xmm_nb = {
.notifier_call = usb_xmm_notify,
};
-static int baseband_xmm_power_driver_probe(struct platform_device *device)
+static int xmm_power_pm_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
{
- struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *)
- device->dev.platform_data;
+ struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
+ unsigned long flags;
+
+ if (!pdata)
+ return NOTIFY_DONE;
+
+ pr_debug("%s: event %ld\n", __func__, event);
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ pr_debug("%s : PM_SUSPEND_PREPARE\n", __func__);
+ if (wake_lock_active(&wakelock)) {
+ pr_info("%s: wakelock was active, aborting suspend\n",
+ __func__);
+ return NOTIFY_STOP;
+ }
+
+ spin_lock_irqsave(&xmm_lock, flags);
+ if (wakeup_pending) {
+ wakeup_pending = false;
+ spin_unlock_irqrestore(&xmm_lock, flags);
+ pr_info("%s : XMM busy : Abort system suspend\n",
+ __func__);
+ return NOTIFY_STOP;
+ }
+ system_suspending = true;
+ spin_unlock_irqrestore(&xmm_lock, flags);
+ return NOTIFY_OK;
+ case PM_POST_SUSPEND:
+ pr_debug("%s : PM_POST_SUSPEND\n", __func__);
+ spin_lock_irqsave(&xmm_lock, flags);
+ system_suspending = false;
+ if (wakeup_pending &&
+ (baseband_xmm_powerstate == BBXMM_PS_L2)) {
+ wakeup_pending = false;
+ spin_unlock_irqrestore(&xmm_lock, flags);
+ pr_info("%s : Service Pending CP wakeup\n", __func__);
+ CP_initiated_L2toL0 = true;
+ baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
+ return NOTIFY_OK;
+ }
+ wakeup_pending = false;
+ spin_unlock_irqrestore(&xmm_lock, flags);
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block xmm_power_pm_notifier = {
+ .notifier_call = xmm_power_pm_notifier_event,
+};
+
+
+static int xmm_power_driver_probe(struct platform_device *device)
+{
+ struct baseband_power_platform_data *pdata = device->dev.platform_data;
struct device *dev = &device->dev;
unsigned long flags;
int err;
@@ -784,17 +902,17 @@ static int baseband_xmm_power_driver_probe(struct platform_device *device)
pr_debug("[XMM] enum_delay_ms=%ld\n", enum_delay_ms);
/* check for platform data */
- if (!data)
+ if (!pdata)
return -ENODEV;
/* check if supported modem */
- if (data->baseband_type != BASEBAND_XMM) {
+ if (pdata->baseband_type != BASEBAND_XMM) {
pr_err("unsuppported modem\n");
return -ENODEV;
}
/* save platform data */
- baseband_power_driver_data = data;
+ xmm_power_drv_data.pdata = pdata;
/* create device file */
err = device_create_file(dev, &dev_attr_xmm_onoff);
@@ -809,20 +927,14 @@ static int baseband_xmm_power_driver_probe(struct platform_device *device)
/* init spin lock */
spin_lock_init(&xmm_lock);
/* request baseband gpio(s) */
- tegra_baseband_gpios[0].gpio = baseband_power_driver_data
- ->modem.xmm.bb_rst;
- tegra_baseband_gpios[1].gpio = baseband_power_driver_data
- ->modem.xmm.bb_on;
- tegra_baseband_gpios[2].gpio = baseband_power_driver_data
- ->modem.xmm.ipc_bb_wake;
- tegra_baseband_gpios[3].gpio = baseband_power_driver_data
- ->modem.xmm.ipc_ap_wake;
- tegra_baseband_gpios[4].gpio = baseband_power_driver_data
- ->modem.xmm.ipc_hsic_active;
- tegra_baseband_gpios[5].gpio = baseband_power_driver_data
- ->modem.xmm.ipc_hsic_sus_req;
+ tegra_baseband_gpios[0].gpio = pdata->modem.xmm.bb_rst;
+ tegra_baseband_gpios[1].gpio = pdata->modem.xmm.bb_on;
+ tegra_baseband_gpios[2].gpio = pdata->modem.xmm.ipc_bb_wake;
+ tegra_baseband_gpios[3].gpio = pdata->modem.xmm.ipc_ap_wake;
+ tegra_baseband_gpios[4].gpio = pdata->modem.xmm.ipc_hsic_active;
+ tegra_baseband_gpios[5].gpio = pdata->modem.xmm.ipc_hsic_sus_req;
err = gpio_request_array(tegra_baseband_gpios,
- ARRAY_SIZE(tegra_baseband_gpios));
+ ARRAY_SIZE(tegra_baseband_gpios));
if (err < 0) {
pr_err("%s - request gpio(s) failed\n", __func__);
return -ENODEV;
@@ -833,90 +945,76 @@ static int baseband_xmm_power_driver_probe(struct platform_device *device)
pr_debug("%s: request_irq IPC_AP_WAKE_IRQ\n", __func__);
ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
err = request_threaded_irq(
- gpio_to_irq(data->modem.xmm.ipc_ap_wake),
- NULL,
- baseband_xmm_power_ipc_ap_wake_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "IPC_AP_WAKE_IRQ",
- NULL);
+ gpio_to_irq(pdata->modem.xmm.ipc_ap_wake),
+ NULL, xmm_power_ipc_ap_wake_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "IPC_AP_WAKE_IRQ", NULL);
if (err < 0) {
pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
__func__);
return err;
}
- err = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
+ err = enable_irq_wake(gpio_to_irq(
+ pdata->modem.xmm.ipc_ap_wake));
if (err < 0)
- pr_err("%s: enable_irq_wake error\n", __func__);
- ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
- if (modem_ver >= XMM_MODEM_VER_1130) {
- pr_debug("%s: ver > 1130: AP_WAKE_INIT1\n", __func__);
- /* ver 1130 or later starts in INIT1 state */
- ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
- }
+ pr_err("%s: enable_irq_wake error\n", __func__);
+
+ pr_debug("%s: AP_WAKE_INIT1\n", __func__);
+ /* ver 1130 or later starts in INIT1 state */
+ ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
}
/* init work queue */
- workqueue = create_singlethread_workqueue
- ("baseband_xmm_power_workqueue");
+ workqueue = create_singlethread_workqueue("xmm_power_wq");
if (!workqueue) {
pr_err("cannot create workqueue\n");
- return -1;
+ return -ENOMEM;
}
- baseband_xmm_power_work = (struct baseband_xmm_power_work_t *)
- kmalloc(sizeof(struct baseband_xmm_power_work_t), GFP_KERNEL);
- if (!baseband_xmm_power_work) {
- pr_err("cannot allocate baseband_xmm_power_work\n");
- return -1;
- }
- INIT_WORK((struct work_struct *) baseband_xmm_power_work,
- baseband_xmm_power_work_func);
- baseband_xmm_power_work->state = BBXMM_WORK_INIT;
- queue_work(workqueue,
- (struct work_struct *) baseband_xmm_power_work);
+
+ INIT_WORK(&xmm_power_drv_data.work, xmm_power_work_func);
+ xmm_power_drv_data.state = BBXMM_WORK_INIT;
+ queue_work(workqueue, &xmm_power_drv_data.work);
/* init work objects */
- INIT_WORK(&init1_work, baseband_xmm_power_init1_work);
- INIT_WORK(&init2_work, baseband_xmm_power_init2_work);
- INIT_WORK(&L2_resume_work, baseband_xmm_power_L2_resume_work);
- INIT_WORK(&autopm_resume_work, baseband_xmm_power_autopm_resume);
+ INIT_WORK(&init1_work, xmm_power_init1_work);
+ INIT_WORK(&init2_work, xmm_power_init2_work);
+ INIT_WORK(&L2_resume_work, xmm_power_L2_resume_work);
+ INIT_WORK(&autopm_resume_work, xmm_power_autopm_resume);
/* init state variables */
register_hsic_device = true;
CP_initiated_L2toL0 = false;
- spin_lock_irqsave(&xmm_lock, flags);
baseband_xmm_powerstate = BBXMM_PS_UNINIT;
+ spin_lock_irqsave(&xmm_lock, flags);
wakeup_pending = false;
+ system_suspending = false;
spin_unlock_irqrestore(&xmm_lock, flags);
usb_register_notify(&usb_xmm_nb);
+ register_pm_notifier(&xmm_power_pm_notifier);
pr_debug("%s }\n", __func__);
return 0;
}
-static int baseband_xmm_power_driver_remove(struct platform_device *device)
+static int xmm_power_driver_remove(struct platform_device *device)
{
- struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *)
- device->dev.platform_data;
+ struct baseband_power_platform_data *pdata = device->dev.platform_data;
+ struct xmm_power_data *data = &xmm_power_drv_data;
struct device *dev = &device->dev;
pr_debug("%s\n", __func__);
/* check for platform data */
- if (!data)
+ if (!pdata)
return 0;
+ unregister_pm_notifier(&xmm_power_pm_notifier);
usb_unregister_notify(&usb_xmm_nb);
- /* free work structure */
- kfree(baseband_xmm_power_work);
- baseband_xmm_power_work = (struct baseband_xmm_power_work_t *) 0;
-
/* free baseband irq(s) */
if (modem_flash && modem_pm) {
- free_irq(gpio_to_irq(baseband_power_driver_data
- ->modem.xmm.ipc_ap_wake), NULL);
+ free_irq(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake), NULL);
}
/* free baseband gpio(s) */
@@ -930,23 +1028,23 @@ static int baseband_xmm_power_driver_remove(struct platform_device *device)
device_remove_file(dev, &dev_attr_xmm_onoff);
/* unregister usb host controller */
- if (data->hsic_unregister)
- data->hsic_unregister(data->modem.xmm.hsic_device);
+ if (pdata->hsic_unregister)
+ pdata->hsic_unregister(data->hsic_device);
else
pr_err("%s: hsic_unregister is missing\n", __func__);
return 0;
}
-static int baseband_xmm_power_driver_handle_resume(
- struct baseband_power_platform_data *data)
+static int xmm_power_driver_handle_resume(
+ struct baseband_power_platform_data *pdata)
{
int value;
int delay = 1000; /* maxmum delay in msec */
unsigned long flags;
pr_debug("%s\n", __func__);
- if (!data)
+ if (!pdata)
return 0;
/* check if modem is on */
@@ -956,29 +1054,30 @@ static int baseband_xmm_power_driver_handle_resume(
}
modem_sleep_flag = false;
+ spin_lock_irqsave(&xmm_lock, flags);
+ wakeup_pending = false;
+ spin_unlock_irqrestore(&xmm_lock, flags);
/* L3->L0 */
baseband_xmm_set_power_status(BBXMM_PS_L3TOL0);
- value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
+ value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
if (value) {
pr_info("AP L3 -> L0\n");
- /* wake bb */
- gpio_set_value(data->modem.xmm.ipc_bb_wake, 1);
-
pr_debug("waiting for host wakeup...\n");
+ /* wake bb */
+ gpio_set_value(pdata->modem.xmm.ipc_bb_wake, 1);
do {
mdelay(1);
- value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
+ value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
delay--;
} while ((value) && (delay));
if (delay)
pr_debug("gpio host wakeup low <-\n");
+ else
+ pr_info("!!AP L3->L0 Failed\n");
+
} else {
pr_info("CP L3 -> L0\n");
- spin_lock_irqsave(&xmm_lock, flags);
- /* Clear wakeup pending flag */
- wakeup_pending = false;
- spin_unlock_irqrestore(&xmm_lock, flags);
}
reenable_autosuspend = true;
@@ -986,32 +1085,32 @@ static int baseband_xmm_power_driver_handle_resume(
}
+
#ifdef CONFIG_PM
-static int baseband_xmm_power_driver_suspend(struct device *dev)
+static int xmm_power_driver_suspend(struct device *dev)
{
pr_debug("%s\n", __func__);
return 0;
}
-static int baseband_xmm_power_driver_resume(struct device *dev)
+static int xmm_power_driver_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
- struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *)
- pdev->dev.platform_data;
+ struct baseband_power_platform_data *pdata = pdev->dev.platform_data;
pr_debug("%s\n", __func__);
- baseband_xmm_power_driver_handle_resume(data);
+ xmm_power_driver_handle_resume(pdata);
return 0;
}
-static int baseband_xmm_power_suspend_noirq(struct device *dev)
+static int xmm_power_suspend_noirq(struct device *dev)
{
unsigned long flags;
pr_debug("%s\n", __func__);
spin_lock_irqsave(&xmm_lock, flags);
+ system_suspending = false;
if (wakeup_pending) {
wakeup_pending = false;
spin_unlock_irqrestore(&xmm_lock, flags);
@@ -1022,42 +1121,62 @@ static int baseband_xmm_power_suspend_noirq(struct device *dev)
return 0;
}
-static int baseband_xmm_power_resume_noirq(struct device *dev)
+static int xmm_power_resume_noirq(struct device *dev)
{
pr_debug("%s\n", __func__);
return 0;
}
-static const struct dev_pm_ops baseband_xmm_power_dev_pm_ops = {
- .suspend_noirq = baseband_xmm_power_suspend_noirq,
- .resume_noirq = baseband_xmm_power_resume_noirq,
- .suspend = baseband_xmm_power_driver_suspend,
- .resume = baseband_xmm_power_driver_resume,
+static const struct dev_pm_ops xmm_power_dev_pm_ops = {
+ .suspend_noirq = xmm_power_suspend_noirq,
+ .resume_noirq = xmm_power_resume_noirq,
+ .suspend = xmm_power_driver_suspend,
+ .resume = xmm_power_driver_resume,
};
#endif
+static void xmm_power_driver_shutdown(struct platform_device *device)
+{
+ struct baseband_power_platform_data *pdata = device->dev.platform_data;
+
+ pr_debug("%s\n", __func__);
+ disable_irq(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
+ /* bb_on is already down, to make sure set 0 again */
+ gpio_set_value(pdata->modem.xmm.bb_on, 0);
+ gpio_set_value(pdata->modem.xmm.bb_rst, 0);
+ return;
+}
+
static struct platform_driver baseband_power_driver = {
- .probe = baseband_xmm_power_driver_probe,
- .remove = baseband_xmm_power_driver_remove,
+ .probe = xmm_power_driver_probe,
+ .remove = xmm_power_driver_remove,
+ .shutdown = xmm_power_driver_shutdown,
.driver = {
.name = "baseband_xmm_power",
#ifdef CONFIG_PM
- .pm = &baseband_xmm_power_dev_pm_ops,
+ .pm = &xmm_power_dev_pm_ops,
#endif
},
};
-static int __init baseband_xmm_power_init(void)
+static int __init xmm_power_init(void)
{
pr_debug("%s\n", __func__);
+
+ INIT_DELAYED_WORK(&pm_qos_work, pm_qos_worker);
+ pm_qos_add_request(&boost_cpu_freq_req, PM_QOS_CPU_FREQ_MIN,
+ (s32)PM_QOS_CPU_FREQ_MIN_DEFAULT_VALUE);
+
return platform_driver_register(&baseband_power_driver);
}
-static void __exit baseband_xmm_power_exit(void)
+static void __exit xmm_power_exit(void)
{
pr_debug("%s\n", __func__);
platform_driver_unregister(&baseband_power_driver);
+
+ pm_qos_remove_request(&boost_cpu_freq_req);
}
-module_init(baseband_xmm_power_init)
-module_exit(baseband_xmm_power_exit)
+module_init(xmm_power_init)
+module_exit(xmm_power_exit)
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.h b/arch/arm/mach-tegra/baseband-xmm-power.h
index 0768ed1..1f08e3b 100644
--- a/arch/arm/mach-tegra/baseband-xmm-power.h
+++ b/arch/arm/mach-tegra/baseband-xmm-power.h
@@ -71,24 +71,19 @@ enum baseband_xmm_power_work_state_t {
BBXMM_WORK_INIT_FLASH_STEP1,
/* initialize flash (with power management support) modem */
BBXMM_WORK_INIT_FLASH_PM_STEP1,
- BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1,
- BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1,
/* initialize flashless (with power management support) modem */
BBXMM_WORK_INIT_FLASHLESS_PM_STEP1,
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ,
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1,
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2,
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1,
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2,
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3,
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4,
+ BBXMM_WORK_INIT_FLASHLESS_PM_STEP2,
+ BBXMM_WORK_INIT_FLASHLESS_PM_STEP3,
+ BBXMM_WORK_INIT_FLASHLESS_PM_STEP4,
};
-struct baseband_xmm_power_work_t {
- /* work structure must be first structure member */
- struct work_struct work;
+struct xmm_power_data {
/* xmm modem state */
enum baseband_xmm_power_work_state_t state;
+ struct baseband_power_platform_data *pdata;
+ struct work_struct work;
+ struct platform_device *hsic_device;
};
enum baseband_xmm_powerstate_t {
@@ -104,8 +99,9 @@ enum baseband_xmm_powerstate_t {
BBXMM_PS_LAST = -1,
};
-irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id);
+irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id);
void baseband_xmm_set_power_status(unsigned int status);
+extern struct xmm_power_data xmm_power_drv_data;
#endif /* BASREBAND_XMM_POWER_H */
diff --git a/arch/arm/mach-tegra/baseband-xmm-power2.c b/arch/arm/mach-tegra/baseband-xmm-power2.c
index 4295b39..3c6285c 100644
--- a/arch/arm/mach-tegra/baseband-xmm-power2.c
+++ b/arch/arm/mach-tegra/baseband-xmm-power2.c
@@ -32,8 +32,6 @@
#include "board.h"
#include "devices.h"
-MODULE_LICENSE("GPL");
-
static unsigned long XYZ = 1000 * 1000000 + 800 * 1000 + 500;
module_param(modem_ver, ulong, 0644);
@@ -49,9 +47,8 @@ module_param(XYZ, ulong, 0644);
MODULE_PARM_DESC(XYZ,
"baseband xmm power2 - timing parameters X/Y/Z delay in ms");
-static struct baseband_power_platform_data *baseband_power2_driver_data;
static struct workqueue_struct *workqueue;
-static struct baseband_xmm_power_work_t *baseband_xmm_power2_work;
+static bool free_ipc_ap_wake_irq;
static enum {
IPC_AP_WAKE_UNINIT,
@@ -62,105 +59,37 @@ static enum {
IPC_AP_WAKE_H,
} ipc_ap_wake_state;
-static irqreturn_t baseband_xmm_power2_ver_lt_1130_ipc_ap_wake_irq2
- (int irq, void *dev_id)
-{
- int value;
-
- pr_debug("%s\n", __func__);
-
- /* check for platform data */
- if (!baseband_power2_driver_data)
- return IRQ_HANDLED;
- value = gpio_get_value(baseband_power2_driver_data->
- modem.xmm.ipc_ap_wake);
-
- /* IPC_AP_WAKE state machine */
- if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
- pr_err("%s - spurious irq\n", __func__);
- } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
- if (!value) {
- pr_debug("%s - IPC_AP_WAKE_INIT1"
- " - got falling edge\n",
- __func__);
- /* go to IPC_AP_WAKE_INIT1 state */
- ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
- /* queue work */
- baseband_xmm_power2_work->state =
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1;
- queue_work(workqueue, (struct work_struct *)
- baseband_xmm_power2_work);
- } else {
- pr_debug("%s - IPC_AP_WAKE_INIT1"
- " - wait for falling edge\n",
- __func__);
- }
- } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
- if (!value) {
- pr_debug("%s - IPC_AP_WAKE_INIT2"
- " - wait for rising edge\n",
- __func__);
- } else {
- pr_debug("%s - IPC_AP_WAKE_INIT2"
- " - got rising edge\n",
- __func__);
- /* go to IPC_AP_WAKE_INIT2 state */
- ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
- /* queue work */
- baseband_xmm_power2_work->state =
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2;
- queue_work(workqueue, (struct work_struct *)
- baseband_xmm_power2_work);
- }
- } else {
- if (!value) {
- pr_debug("%s - falling\n", __func__);
- ipc_ap_wake_state = IPC_AP_WAKE_L;
- } else {
- pr_debug("%s - rising\n", __func__);
- ipc_ap_wake_state = IPC_AP_WAKE_H;
- }
- return baseband_xmm_power_ipc_ap_wake_irq(irq, dev_id);
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2
- (int irq, void *dev_id)
+static irqreturn_t xmm_power2_ipc_ap_wake_irq(int irq, void *dev_id)
{
int value;
+ struct xmm_power_data *data = dev_id;
+ struct baseband_power_platform_data *pdata = data->pdata;
pr_debug("%s\n", __func__);
/* check for platform data */
- if (!baseband_power2_driver_data)
+ if (!pdata)
return IRQ_HANDLED;
- value = gpio_get_value(baseband_power2_driver_data->
- modem.xmm.ipc_ap_wake);
+ value = gpio_get_value(pdata->modem.xmm.ipc_ap_wake);
/* IPC_AP_WAKE state machine */
- if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
+ if (unlikely(ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY))
pr_err("%s - spurious irq\n", __func__);
- } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
+ else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
if (!value) {
- pr_debug("%s - IPC_AP_WAKE_INIT1"
- " - got falling edge\n",
+ pr_debug("%s: IPC_AP_WAKE_INIT1 got falling edge\n",
__func__);
/* go to IPC_AP_WAKE_INIT2 state */
ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
/* queue work */
- baseband_xmm_power2_work->state =
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2;
- queue_work(workqueue, (struct work_struct *)
- baseband_xmm_power2_work);
- } else {
- pr_debug("%s - IPC_AP_WAKE_INIT1"
- " - wait for falling edge\n",
- __func__);
- }
+ data->state =
+ BBXMM_WORK_INIT_FLASHLESS_PM_STEP2;
+ queue_work(workqueue, &data->work);
+ } else
+ pr_debug("%s: IPC_AP_WAKE_INIT1"
+ " wait for falling edge\n", __func__);
} else {
if (!value) {
pr_debug("%s - falling\n", __func__);
@@ -169,260 +98,154 @@ static irqreturn_t baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2
pr_debug("%s - rising\n", __func__);
ipc_ap_wake_state = IPC_AP_WAKE_H;
}
- return baseband_xmm_power_ipc_ap_wake_irq(irq, dev_id);
+ return xmm_power_ipc_ap_wake_irq(irq, dev_id);
}
return IRQ_HANDLED;
}
-static void baseband_xmm_power2_flashless_pm_ver_lt_1130_step1
- (struct work_struct *work)
-{
- int value;
-
- pr_debug("%s {\n", __func__);
-
- /* check for platform data */
- if (!baseband_power2_driver_data)
- return;
-
- /* check if IPC_HSIC_ACTIVE high */
- value = gpio_get_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active);
- if (value != 1) {
- pr_err("%s - expected IPC_HSIC_ACTIVE high!\n", __func__);
- return;
- }
-
- /* wait 30 ms */
- mdelay(30);
-
- /* set IPC_HSIC_ACTIVE low */
- gpio_set_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active, 0);
-
- pr_debug("%s }\n", __func__);
-}
-
-static void baseband_xmm_power2_flashless_pm_ver_lt_1130_step2
- (struct work_struct *work)
-{
- int value;
-
- pr_debug("%s {\n", __func__);
-
- /* check for platform data */
- if (!baseband_power2_driver_data)
- return;
-
- /* check if IPC_HSIC_ACTIVE low */
- value = gpio_get_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active);
- if (value != 0) {
- pr_err("%s - expected IPC_HSIC_ACTIVE low!\n", __func__);
- return;
- }
-
- /* wait 1 ms */
- mdelay(1);
-
- /* unregister usb host controller */
- if (baseband_power2_driver_data->hsic_unregister)
- baseband_power2_driver_data->hsic_unregister(
- baseband_power2_driver_data->modem.xmm.hsic_device);
- else
- pr_err("%s: hsic_unregister is missing\n", __func__);
-
- /* set IPC_HSIC_ACTIVE high */
- gpio_set_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active, 1);
-
- /* wait 20 ms */
- mdelay(20);
-
- /* set IPC_HSIC_ACTIVE low */
- gpio_set_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active, 0);
-
- /* wait 20 ms */
- mdelay(20);
-
- /* set IPC_HSIC_ACTIVE high */
- gpio_set_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active, 1);
-
- pr_debug("%s }\n", __func__);
-}
-
-static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step1
- (struct work_struct *work)
+static void xmm_power2_step1(struct work_struct *work)
{
+ struct xmm_power_data *data =
+ container_of(work, struct xmm_power_data, work);
+ struct baseband_power_platform_data *pdata = data->pdata;
int X = XYZ / 1000000;
- int Y = XYZ / 1000 - X * 1000;
- int Z = XYZ % 1000;
pr_info("%s {\n", __func__);
- pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
-
/* check for platform data */
- if (!baseband_power2_driver_data)
+ if (!pdata)
return;
/* unregister usb host controller */
- if (baseband_power2_driver_data->hsic_unregister)
- baseband_power2_driver_data->hsic_unregister(
- baseband_power2_driver_data->modem.xmm.hsic_device);
+ if (pdata->hsic_unregister)
+ pdata->hsic_unregister(data->hsic_device);
else
pr_err("%s: hsic_unregister is missing\n", __func__);
/* wait X ms */
- mdelay(X);
+ msleep(X);
/* set IPC_HSIC_ACTIVE low */
- gpio_set_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active, 0);
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
pr_info("%s }\n", __func__);
}
-static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step2
- (struct work_struct *work)
+static void xmm_power2_step2(struct work_struct *work)
{
+ struct xmm_power_data *data =
+ container_of(work, struct xmm_power_data, work);
+ struct baseband_power_platform_data *pdata = data->pdata;
int X = XYZ / 1000000;
int Y = XYZ / 1000 - X * 1000;
int Z = XYZ % 1000;
pr_info("%s {\n", __func__);
- pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
-
/* check for platform data */
- if (!baseband_power2_driver_data)
+ if (!data || !pdata)
return;
/* wait Y ms */
- mdelay(Y);
+ msleep(Y);
/* register usb host controller */
- if (baseband_power2_driver_data->hsic_register)
- baseband_power2_driver_data->modem.xmm.hsic_device =
- baseband_power2_driver_data->hsic_register();
+ if (pdata->hsic_register)
+ data->hsic_device = pdata->hsic_register();
else
pr_err("%s: hsic_register is missing\n", __func__);
/* wait Z ms */
- mdelay(Z);
+ msleep(Z);
/* set IPC_HSIC_ACTIVE high */
- gpio_set_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active, 1);
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 1);
/* queue work function to check if enumeration succeeded */
- baseband_xmm_power2_work->state =
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3;
- queue_work(workqueue, (struct work_struct *)
- baseband_xmm_power2_work);
+ data->state = BBXMM_WORK_INIT_FLASHLESS_PM_STEP3;
+ queue_work(workqueue, &data->work);
pr_info("%s }\n", __func__);
}
-static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step3
- (struct work_struct *work)
+static void xmm_power2_step3(struct work_struct *work)
{
- int X = XYZ / 1000000;
- int Y = XYZ / 1000 - X * 1000;
- int Z = XYZ % 1000;
+ struct xmm_power_data *data =
+ container_of(work, struct xmm_power_data, work);
+ struct baseband_power_platform_data *pdata = data->pdata;
int enum_success = 0;
+ mm_segment_t oldfs;
+ struct file *filp;
pr_info("%s {\n", __func__);
- pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
-
/* check for platform data */
- if (!baseband_power2_driver_data)
+ if (!data || !pdata)
return;
- /* wait 500 ms */
- mdelay(500);
+ /* wait 1 sec */
+ msleep(1000);
/* check if enumeration succeeded */
- {
- mm_segment_t oldfs;
- struct file *filp;
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- filp = filp_open("/dev/ttyACM0",
- O_RDONLY, 0);
- if (IS_ERR(filp) || (filp == NULL)) {
- pr_err("/dev/ttyACM0 %ld\n",
- PTR_ERR(filp));
- } else {
- filp_close(filp, NULL);
- enum_success = 1;
- }
- set_fs(oldfs);
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ filp = filp_open("/dev/ttyACM0", O_RDONLY, 0);
+ if (IS_ERR(filp) || (filp == NULL))
+ pr_err("failed to open /dev/ttyACM0 %ld\n", PTR_ERR(filp));
+ else {
+ filp_close(filp, NULL);
+ enum_success = 1;
}
+ set_fs(oldfs);
/* if enumeration failed, attempt recovery pulse */
if (!enum_success) {
pr_info("attempting recovery pulse...\n");
/* wait 20 ms */
- mdelay(20);
+ msleep(20);
/* set IPC_HSIC_ACTIVE low */
- gpio_set_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active, 0);
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
/* wait 20 ms */
- mdelay(20);
+ msleep(20);
/* set IPC_HSIC_ACTIVE high */
- gpio_set_value(baseband_power2_driver_data->
- modem.xmm.ipc_hsic_active, 1);
+ gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 1);
/* check if recovery pulse worked */
- baseband_xmm_power2_work->state =
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4;
- queue_work(workqueue, (struct work_struct *)
- baseband_xmm_power2_work);
+ data->state = BBXMM_WORK_INIT_FLASHLESS_PM_STEP4;
+ queue_work(workqueue, &data->work);
}
pr_info("%s }\n", __func__);
}
-static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step4
- (struct work_struct *work)
+static void xmm_power2_step4(struct work_struct *work)
{
- int X = XYZ / 1000000;
- int Y = XYZ / 1000 - X * 1000;
- int Z = XYZ % 1000;
+ struct xmm_power_data *data =
+ container_of(work, struct xmm_power_data, work);
+ mm_segment_t oldfs;
+ struct file *filp;
int enum_success = 0;
pr_info("%s {\n", __func__);
- pr_info("XYZ=%ld X=%d Y=%d Z=%d\n", XYZ, X, Y, Z);
-
/* check for platform data */
- if (!baseband_power2_driver_data)
+ if (!data)
return;
/* wait 500 ms */
- mdelay(500);
+ msleep(500);
/* check if enumeration succeeded */
- {
- mm_segment_t oldfs;
- struct file *filp;
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- filp = filp_open("/dev/ttyACM0",
- O_RDONLY, 0);
- if (IS_ERR(filp) || (filp == NULL)) {
- pr_err("open /dev/ttyACM0 failed %ld\n",
- PTR_ERR(filp));
- } else {
- filp_close(filp, NULL);
- enum_success = 1;
- }
- set_fs(oldfs);
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ filp = filp_open("/dev/ttyACM0", O_RDONLY, 0);
+ if (IS_ERR(filp) || (filp == NULL))
+ pr_err("failed to open /dev/ttyACM0 %ld\n", PTR_ERR(filp));
+ else {
+ filp_close(filp, NULL);
+ enum_success = 1;
}
+ set_fs(oldfs);
/* if recovery pulse did not fix enumeration, retry from beginning */
if (!enum_success) {
@@ -438,34 +261,31 @@ static void baseband_xmm_power2_flashless_pm_ver_ge_1130_step4
retry);
--retry;
ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
- baseband_xmm_power2_work->state =
- BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
- queue_work(workqueue, (struct work_struct *)
- baseband_xmm_power2_work);
+ data->state = BBXMM_WORK_INIT_FLASHLESS_PM_STEP1;
+ queue_work(workqueue, &data->work);
}
}
pr_info("%s }\n", __func__);
}
-static int free_ipc_ap_wake_irq;
-
-static void baseband_xmm_power2_work_func(struct work_struct *work)
+static void xmm_power2_work_func(struct work_struct *work)
{
- struct baseband_xmm_power_work_t *bbxmm_work
- = (struct baseband_xmm_power_work_t *) work;
+ struct xmm_power_data *data =
+ container_of(work, struct xmm_power_data, work);
+ struct baseband_power_platform_data *pdata = data->pdata;
int err;
- pr_debug("%s bbxmm_work->state=%d\n", __func__, bbxmm_work->state);
+ pr_debug("%s pdata->state=%d\n", __func__, data->state);
- switch (bbxmm_work->state) {
+ switch (data->state) {
case BBXMM_WORK_UNINIT:
pr_debug("BBXMM_WORK_UNINIT\n");
/* free baseband irq(s) */
if (free_ipc_ap_wake_irq) {
- free_irq(gpio_to_irq(baseband_power2_driver_data
- ->modem.xmm.ipc_ap_wake), NULL);
- free_ipc_ap_wake_irq = 0;
+ free_irq(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake),
+ data);
+ free_ipc_ap_wake_irq = false;
}
break;
case BBXMM_WORK_INIT:
@@ -473,24 +293,20 @@ static void baseband_xmm_power2_work_func(struct work_struct *work)
/* request baseband irq(s) */
ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
err = request_threaded_irq(
- gpio_to_irq(baseband_power2_driver_data->
- modem.xmm.ipc_ap_wake),
- NULL,
- (modem_ver < XMM_MODEM_VER_1130)
- ? baseband_xmm_power2_ver_lt_1130_ipc_ap_wake_irq2
- : baseband_xmm_power2_ver_ge_1130_ipc_ap_wake_irq2,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "BBXMM_POWER2_IPC_AP_WAKE_IRQ",
- NULL);
+ gpio_to_irq(pdata->modem.xmm.ipc_ap_wake),
+ NULL, xmm_power2_ipc_ap_wake_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "xmm_power2_ipc_ap_wake_irq", data);
if (err < 0) {
pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
__func__);
return;
}
- free_ipc_ap_wake_irq = 1;
+ free_ipc_ap_wake_irq = true;
ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
+
/* go to next state */
- bbxmm_work->state = (modem_flash && !modem_pm)
+ data->state = (modem_flash && !modem_pm)
? BBXMM_WORK_INIT_FLASH_STEP1
: (modem_flash && modem_pm)
? BBXMM_WORK_INIT_FLASH_PM_STEP1
@@ -501,130 +317,93 @@ static void baseband_xmm_power2_work_func(struct work_struct *work)
break;
case BBXMM_WORK_INIT_FLASH_STEP1:
pr_debug("BBXMM_WORK_INIT_FLASH_STEP1\n");
+ pr_info("%s: flashed modem is not supported here\n", __func__);
break;
case BBXMM_WORK_INIT_FLASH_PM_STEP1:
pr_debug("BBXMM_WORK_INIT_FLASH_PM_STEP1\n");
- /* go to next state */
- bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
- ? BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1
- : BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1;
- queue_work(workqueue, work);
- break;
- case BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1:
- pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_LT_1130_STEP1\n");
- break;
- case BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1:
- pr_debug("BBXMM_WORK_INIT_FLASH_PM_VER_GE_1130_STEP1\n");
+ pr_info("%s: flashed modem is not supported here\n", __func__);
break;
case BBXMM_WORK_INIT_FLASHLESS_PM_STEP1:
+ /* start flashless modem enum process */
pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP1\n");
- /* go to next state */
- bbxmm_work->state = (modem_ver < XMM_MODEM_VER_1130)
- ? BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ
- : BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1;
- queue_work(workqueue, work);
- break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_WAIT_IRQ"
- " - waiting for IPC_AP_WAKE_IRQ to trigger step1\n");
- break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP1\n");
- baseband_xmm_power2_flashless_pm_ver_lt_1130_step1(work);
+ xmm_power2_step1(work);
break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_LT_1130_STEP2\n");
- baseband_xmm_power2_flashless_pm_ver_lt_1130_step2(work);
+ case BBXMM_WORK_INIT_FLASHLESS_PM_STEP2:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP2\n");
+ xmm_power2_step2(work);
break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP1\n");
- baseband_xmm_power2_flashless_pm_ver_ge_1130_step1(work);
+ case BBXMM_WORK_INIT_FLASHLESS_PM_STEP3:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP3\n");
+ xmm_power2_step3(work);
break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP2\n");
- baseband_xmm_power2_flashless_pm_ver_ge_1130_step2(work);
+ case BBXMM_WORK_INIT_FLASHLESS_PM_STEP4:
+ pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_STEP4\n");
+ xmm_power2_step4(work);
break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP3\n");
- baseband_xmm_power2_flashless_pm_ver_ge_1130_step3(work);
- break;
- case BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4:
- pr_debug("BBXMM_WORK_INIT_FLASHLESS_PM_VER_GE_1130_STEP4\n");
- baseband_xmm_power2_flashless_pm_ver_ge_1130_step4(work);
+ default:
break;
}
-
}
-static int baseband_xmm_power2_driver_probe(struct platform_device *device)
+static int xmm_power2_probe(struct platform_device *device)
{
- struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *)
- device->dev.platform_data;
-
pr_debug("%s\n", __func__);
+ if (!device->dev.platform_data) {
+ pr_err("%s: no platform data found\n", __func__);
+ return -ENOMEM;
+ }
- /* save platform data */
- baseband_power2_driver_data = data;
+ xmm_power_drv_data.pdata = device->dev.platform_data;
- /* init work queue */
+ /* create workqueue */
pr_debug("%s: init work queue\n", __func__);
- workqueue = create_singlethread_workqueue
- ("baseband_xmm_power2_workqueue");
- if (!workqueue) {
- pr_err("cannot create workqueue\n");
- return -1;
- }
- baseband_xmm_power2_work = (struct baseband_xmm_power_work_t *)
- kmalloc(sizeof(struct baseband_xmm_power_work_t), GFP_KERNEL);
- if (!baseband_xmm_power2_work) {
- pr_err("cannot allocate baseband_xmm_power2_work\n");
- return -1;
+ workqueue = create_singlethread_workqueue("xmm_power2_wq");
+ if (unlikely(!workqueue)) {
+ pr_err("%s: cannot create workqueue\n", __func__);
+ return -ENOMEM;
}
+
+ /* init work */
pr_debug("%s: BBXMM_WORK_INIT\n", __func__);
- INIT_WORK((struct work_struct *) baseband_xmm_power2_work,
- baseband_xmm_power2_work_func);
- baseband_xmm_power2_work->state = BBXMM_WORK_INIT;
- queue_work(workqueue,
- (struct work_struct *) baseband_xmm_power2_work);
+ INIT_WORK(&xmm_power_drv_data.work, xmm_power2_work_func);
+ xmm_power_drv_data.state = BBXMM_WORK_INIT;
+ queue_work(workqueue, &xmm_power_drv_data.work);
+
return 0;
}
-static int baseband_xmm_power2_driver_remove(struct platform_device *device)
+static int xmm_power2_remove(struct platform_device *device)
{
- struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *)
+ struct baseband_power_platform_data *pdata =
device->dev.platform_data;
+ struct xmm_power_data *data = &xmm_power_drv_data;
pr_debug("%s\n", __func__);
/* check for platform data */
if (!data)
- return 0;
-
- /* free irq */
- if (free_ipc_ap_wake_irq) {
- free_irq(gpio_to_irq(data->modem.xmm.ipc_ap_wake), NULL);
- free_ipc_ap_wake_irq = 0;
- }
+ return -ENODEV;
- /* free work structure */
+ /* free work queue */
if (workqueue) {
- cancel_work_sync(baseband_xmm_power2_work);
+ cancel_work_sync(&data->work);
destroy_workqueue(workqueue);
}
- kfree(baseband_xmm_power2_work);
- baseband_xmm_power2_work = (struct baseband_xmm_power_work_t *) 0;
+
+ /* free irq */
+ if (free_ipc_ap_wake_irq) {
+ free_irq(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake), data);
+ free_ipc_ap_wake_irq = false;
+ }
return 0;
}
#ifdef CONFIG_PM
-static int baseband_xmm_power2_driver_suspend(struct platform_device *device,
+static int xmm_power2_suspend(struct platform_device *device,
pm_message_t state)
{
- struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *)
+ struct baseband_power_platform_data *data =
device->dev.platform_data;
pr_debug("%s - nop\n", __func__);
@@ -636,10 +415,9 @@ static int baseband_xmm_power2_driver_suspend(struct platform_device *device,
return 0;
}
-static int baseband_xmm_power2_driver_resume(struct platform_device *device)
+static int xmm_power2_resume(struct platform_device *device)
{
- struct baseband_power_platform_data *data
- = (struct baseband_power_platform_data *)
+ struct baseband_power_platform_data *data =
device->dev.platform_data;
pr_debug("%s - nop\n", __func__);
@@ -653,29 +431,32 @@ static int baseband_xmm_power2_driver_resume(struct platform_device *device)
#endif
static struct platform_driver baseband_power2_driver = {
- .probe = baseband_xmm_power2_driver_probe,
- .remove = baseband_xmm_power2_driver_remove,
+ .probe = xmm_power2_probe,
+ .remove = xmm_power2_remove,
#ifdef CONFIG_PM
- .suspend = baseband_xmm_power2_driver_suspend,
- .resume = baseband_xmm_power2_driver_resume,
+ .suspend = xmm_power2_suspend,
+ .resume = xmm_power2_resume,
#endif
.driver = {
.name = "baseband_xmm_power2",
},
};
-static int __init baseband_xmm_power2_init(void)
+static int __init xmm_power2_init(void)
{
pr_debug("%s\n", __func__);
return platform_driver_register(&baseband_power2_driver);
}
-static void __exit baseband_xmm_power2_exit(void)
+static void __exit xmm_power2_exit(void)
{
pr_debug("%s\n", __func__);
+
platform_driver_unregister(&baseband_power2_driver);
}
-module_init(baseband_xmm_power2_init)
-module_exit(baseband_xmm_power2_exit)
+module_init(xmm_power2_init)
+module_exit(xmm_power2_exit)
+
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-tegra/board-aruba-panel.c b/arch/arm/mach-tegra/board-aruba-panel.c
index b014326..0e24a43 100644
--- a/arch/arm/mach-tegra/board-aruba-panel.c
+++ b/arch/arm/mach-tegra/board-aruba-panel.c
@@ -26,7 +26,7 @@
#include <linux/platform_device.h>
#include <linux/pwm_backlight.h>
#include <linux/nvhost.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dc.h>
diff --git a/arch/arm/mach-tegra/board-cardhu-kbc.c b/arch/arm/mach-tegra/board-cardhu-kbc.c
index 3bf0a3b..16e83bb 100644
--- a/arch/arm/mach-tegra/board-cardhu-kbc.c
+++ b/arch/arm/mach-tegra/board-cardhu-kbc.c
@@ -174,7 +174,8 @@ static struct gpio_keys_button cardhu_keys_e1291_a04[] = {
[3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
[4] = GPIO_KEY(KEY_BACK, PQ0, 0),
[5] = GPIO_KEY(KEY_MENU, PQ1, 0),
- [6] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100),
+ [6] = GPIO_KEY(KEY_RESERVED, PV0, 1),
+ [7] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100),
};
static struct gpio_keys_platform_data cardhu_keys_e1291_pdata = {
@@ -200,7 +201,7 @@ static struct gpio_keys_button cardhu_pm298_int_keys[] = {
};
static struct gpio_keys_button cardhu_pm299_int_keys[] = {
- [0] = GPIO_IKEY(KEY_POWER, RICOH583_IRQ_BASE + RICOH583_IRQ_ONKEY, 1, 100),
+ [0] = GPIO_KEY(KEY_POWER, PV0, 1),
};
static struct gpio_keys_platform_data cardhu_int_keys_pdata = {
@@ -230,6 +231,7 @@ int __init cardhu_keys_init(void)
(board_info.board_id == BOARD_E1257) ||
(board_info.board_id == BOARD_PM305) ||
(board_info.board_id == BOARD_PM311) ||
+ (board_info.board_id == BOARD_PM267) ||
(board_info.board_id == BOARD_PM269)))
return 0;
@@ -290,6 +292,7 @@ int __init cardhu_keys_init(void)
(board_info.board_id == BOARD_E1186) ||
(board_info.board_id == BOARD_PM305) ||
(board_info.board_id == BOARD_PM311) ||
+ (board_info.board_id == BOARD_PM267) ||
(board_info.board_id == BOARD_PM269)) {
if (get_tegra_image_type() == rck_image)
cardhu_int_keys[0].code = KEY_ENTER;
diff --git a/arch/arm/mach-tegra/board-cardhu-memory.c b/arch/arm/mach-tegra/board-cardhu-memory.c
index 0cd9e00..6eb8633 100644
--- a/arch/arm/mach-tegra/board-cardhu-memory.c
+++ b/arch/arm/mach-tegra/board-cardhu-memory.c
@@ -2539,6 +2539,246 @@ static const struct tegra_emc_table cardhu_emc_tables_h5tc2g_a2_2GB1R[] = {
},
{
0x32, /* Rev 3.2 */
+ 400000, /* SDRAM frequency */
+ {
+ 0x00000012, /* EMC_RC */
+ 0x00000066, /* EMC_RFC */
+ 0x0000000c, /* EMC_RAS */
+ 0x00000004, /* EMC_RP */
+ 0x00000003, /* EMC_R2W */
+ 0x00000008, /* EMC_W2R */
+ 0x00000002, /* EMC_R2P */
+ 0x0000000a, /* EMC_W2P */
+ 0x00000004, /* EMC_RD_RCD */
+ 0x00000004, /* EMC_WR_RCD */
+ 0x00000002, /* EMC_RRD */
+ 0x00000001, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000004, /* EMC_WDV */
+ 0x00000006, /* EMC_QUSE */
+ 0x00000004, /* EMC_QRST */
+ 0x0000000a, /* EMC_QSAFE */
+ 0x0000000d, /* EMC_RDV */
+ 0x00000bf0, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x000002fc, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000001, /* EMC_PDEX2WR */
+ 0x00000008, /* EMC_PDEX2RD */
+ 0x00000001, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x00000008, /* EMC_AR2PDEN */
+ 0x0000000f, /* EMC_RW2PDEN */
+ 0x0000006c, /* EMC_TXSR */
+ 0x00000200, /* EMC_TXSRDLL */
+ 0x00000004, /* EMC_TCKE */
+ 0x0000000c, /* EMC_TFAW */
+ 0x00000000, /* EMC_TRPAB */
+ 0x00000004, /* EMC_TCLKSTABLE */
+ 0x00000005, /* EMC_TCLKSTOP */
+ 0x00000c30, /* EMC_TREFBW */
+ 0x00000000, /* EMC_QUSE_EXTRA */
+ 0x00000006, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00007088, /* EMC_FBIO_CFG5 */
+ 0x001d0084, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x00038000, /* EMC_DLL_XFORM_DQS0 */
+ 0x00038000, /* EMC_DLL_XFORM_DQS1 */
+ 0x00038000, /* EMC_DLL_XFORM_DQS2 */
+ 0x00038000, /* EMC_DLL_XFORM_DQS3 */
+ 0x00038000, /* EMC_DLL_XFORM_DQS4 */
+ 0x00038000, /* EMC_DLL_XFORM_DQS5 */
+ 0x00038000, /* EMC_DLL_XFORM_DQS6 */
+ 0x00038000, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x00030000, /* EMC_DLL_XFORM_DQ0 */
+ 0x00030000, /* EMC_DLL_XFORM_DQ1 */
+ 0x00030000, /* EMC_DLL_XFORM_DQ2 */
+ 0x00030000, /* EMC_DLL_XFORM_DQ3 */
+ 0x000002a0, /* EMC_XM2CMDPADCTRL */
+ 0x0800013d, /* EMC_XM2DQSPADCTRL2 */
+ 0x00000000, /* EMC_XM2DQPADCTRL2 */
+ 0x77fff884, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f508, /* EMC_XM2COMPPADCTRL */
+ 0x05057404, /* EMC_XM2VTTGENPADCTRL */
+ 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x080001e8, /* EMC_XM2QUSEPADCTRL */
+ 0x08000021, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00020000, /* EMC_ZCAL_INTERVAL */
+ 0x00000100, /* EMC_ZCAL_WAIT_CNT */
+ 0x0158000c, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x800018c8, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x00000006, /* MC_EMEM_ARB_CFG */
+ 0x80000048, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000009, /* MC_EMEM_ARB_TIMING_RC */
+ 0x00000005, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x06030202, /* MC_EMEM_ARB_DA_TURNS */
+ 0x000d0709, /* MC_EMEM_ARB_DA_COVERS */
+ 0x7086120a, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xe8000000, /* EMC_FBIO_SPARE */
+ 0xff00ff89, /* EMC_CFG_RSV */
+ },
+ 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000000, /* EMC_CFG.PERIODIC_QRST */
+ 0x80000521, /* Mode Register 0 */
+ 0x80100002, /* Mode Register 1 */
+ 0x80200000, /* Mode Register 2 */
+ 0x00000000, /* EMC_CFG.DYN_SELF_REF */
+ },
+ {
+ 0x32, /* Rev 3.2 */
+ 667000, /* SDRAM frequency */
+ {
+ 0x00000023, /* EMC_RC */
+ 0x000000df, /* EMC_RFC */
+ 0x00000019, /* EMC_RAS */
+ 0x00000009, /* EMC_RP */
+ 0x00000005, /* EMC_R2W */
+ 0x0000000d, /* EMC_W2R */
+ 0x00000004, /* EMC_R2P */
+ 0x00000013, /* EMC_W2P */
+ 0x00000009, /* EMC_RD_RCD */
+ 0x00000009, /* EMC_WR_RCD */
+ 0x00000003, /* EMC_RRD */
+ 0x00000001, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000007, /* EMC_WDV */
+ 0x0000000b, /* EMC_QUSE */
+ 0x00000009, /* EMC_QRST */
+ 0x0000000c, /* EMC_QSAFE */
+ 0x00000011, /* EMC_RDV */
+ 0x00001419, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x000005a6, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000003, /* EMC_PDEX2WR */
+ 0x00000010, /* EMC_PDEX2RD */
+ 0x00000001, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x0000000e, /* EMC_AR2PDEN */
+ 0x00000018, /* EMC_RW2PDEN */
+ 0x000000e9, /* EMC_TXSR */
+ 0x00000200, /* EMC_TXSRDLL */
+ 0x00000005, /* EMC_TCKE */
+ 0x00000017, /* EMC_TFAW */
+ 0x00000000, /* EMC_TRPAB */
+ 0x00000007, /* EMC_TCLKSTABLE */
+ 0x00000008, /* EMC_TCLKSTOP */
+ 0x000016da, /* EMC_TREFBW */
+ 0x0000000c, /* EMC_QUSE_EXTRA */
+ 0x00000004, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00005088, /* EMC_FBIO_CFG5 */
+ 0xf0080191, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x00000008, /* EMC_DLL_XFORM_DQS0 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS1 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS2 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS3 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS4 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS5 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS6 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x0000000c, /* EMC_DLL_XFORM_DQ0 */
+ 0x0000000c, /* EMC_DLL_XFORM_DQ1 */
+ 0x0000000c, /* EMC_DLL_XFORM_DQ2 */
+ 0x0000000c, /* EMC_DLL_XFORM_DQ3 */
+ 0x000002a0, /* EMC_XM2CMDPADCTRL */
+ 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
+ 0x22220000, /* EMC_XM2DQPADCTRL2 */
+ 0x77fff884, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f501, /* EMC_XM2COMPPADCTRL */
+ 0x07077404, /* EMC_XM2VTTGENPADCTRL */
+ 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x080001e8, /* EMC_XM2QUSEPADCTRL */
+ 0x07000021, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00020000, /* EMC_ZCAL_INTERVAL */
+ 0x00000100, /* EMC_ZCAL_WAIT_CNT */
+ 0x00df000c, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x80002d93, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x0000000b, /* MC_EMEM_ARB_CFG */
+ 0x80000087, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000005, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000012, /* MC_EMEM_ARB_TIMING_RC */
+ 0x0000000c, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x0000000b, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x0000000c, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
+ 0x00160d12, /* MC_EMEM_ARB_DA_COVERS */
+ 0x73cc2213, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xf8000000, /* EMC_FBIO_SPARE */
+ 0xff00ff49, /* EMC_CFG_RSV */
+ },
+ 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000001, /* EMC_CFG.PERIODIC_QRST */
+ 0x80000d71, /* Mode Register 0 */
+ 0x80100002, /* Mode Register 1 */
+ 0x80200018, /* Mode Register 2 */
+ 0x00000000, /* EMC_CFG.DYN_SELF_REF */
+ },
+ {
+ 0x32, /* Rev 3.2 */
750000, /* SDRAM frequency */
{
0x00000023, /* EMC_RC */
@@ -2657,6 +2897,126 @@ static const struct tegra_emc_table cardhu_emc_tables_h5tc2g_a2_2GB1R[] = {
0x80200018, /* Mode Register 2 */
0x00000000, /* EMC_CFG.DYN_SELF_REF */
},
+ {
+ 0x32, /* Rev 3.2 */
+ 800000, /* SDRAM frequency */
+ {
+ 0x00000025, /* EMC_RC */
+ 0x000000ce, /* EMC_RFC */
+ 0x0000001a, /* EMC_RAS */
+ 0x00000009, /* EMC_RP */
+ 0x00000005, /* EMC_R2W */
+ 0x0000000d, /* EMC_W2R */
+ 0x00000004, /* EMC_R2P */
+ 0x00000013, /* EMC_W2P */
+ 0x00000009, /* EMC_RD_RCD */
+ 0x00000009, /* EMC_WR_RCD */
+ 0x00000003, /* EMC_RRD */
+ 0x00000001, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000007, /* EMC_WDV */
+ 0x0000000b, /* EMC_QUSE */
+ 0x00000009, /* EMC_QRST */
+ 0x0000000c, /* EMC_QSAFE */
+ 0x00000012, /* EMC_RDV */
+ 0x00001820, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x00000608, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000003, /* EMC_PDEX2WR */
+ 0x00000012, /* EMC_PDEX2RD */
+ 0x00000001, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x0000000f, /* EMC_AR2PDEN */
+ 0x00000018, /* EMC_RW2PDEN */
+ 0x000000d8, /* EMC_TXSR */
+ 0x00000200, /* EMC_TXSRDLL */
+ 0x00000005, /* EMC_TCKE */
+ 0x00000018, /* EMC_TFAW */
+ 0x00000000, /* EMC_TRPAB */
+ 0x00000007, /* EMC_TCLKSTABLE */
+ 0x00000008, /* EMC_TCLKSTOP */
+ 0x00001860, /* EMC_TREFBW */
+ 0x0000000c, /* EMC_QUSE_EXTRA */
+ 0x00000004, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00005088, /* EMC_FBIO_CFG5 */
+ 0xf0070191, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x0000c008, /* EMC_DLL_XFORM_DQS0 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS1 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS2 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS3 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS4 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS5 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS6 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x007f800c, /* EMC_DLL_XFORM_DQ0 */
+ 0x007f800c, /* EMC_DLL_XFORM_DQ1 */
+ 0x007f800c, /* EMC_DLL_XFORM_DQ2 */
+ 0x007f800c, /* EMC_DLL_XFORM_DQ3 */
+ 0x000002a0, /* EMC_XM2CMDPADCTRL */
+ 0x0600013d, /* EMC_XM2DQSPADCTRL2 */
+ 0x22220000, /* EMC_XM2DQPADCTRL2 */
+ 0x77fff884, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f501, /* EMC_XM2COMPPADCTRL */
+ 0x07077404, /* EMC_XM2VTTGENPADCTRL */
+ 0x54000000, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x080001e8, /* EMC_XM2QUSEPADCTRL */
+ 0x07000021, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00020000, /* EMC_ZCAL_INTERVAL */
+ 0x00000100, /* EMC_ZCAL_WAIT_CNT */
+ 0x00f0000c, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x8000308c, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x0000000c, /* MC_EMEM_ARB_CFG */
+ 0x80000090, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000005, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000013, /* MC_EMEM_ARB_TIMING_RC */
+ 0x0000000c, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x0000000b, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x0000000c, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000008, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x08040202, /* MC_EMEM_ARB_DA_TURNS */
+ 0x00160d13, /* MC_EMEM_ARB_DA_COVERS */
+ 0x712c2414, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xf8000000, /* EMC_FBIO_SPARE */
+ 0xff00ff49, /* EMC_CFG_RSV */
+ },
+ 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000001, /* EMC_CFG.PERIODIC_QRST */
+ 0x80000d71, /* Mode Register 0 */
+ 0x80100002, /* Mode Register 1 */
+ 0x80200018, /* Mode Register 2 */
+ 0x00000000, /* EMC_CFG.DYN_SELF_REF */
+ },
};
static const struct tegra_emc_table cardhu_emc_tables_k4b4g0846b_hyk0[] = {
diff --git a/arch/arm/mach-tegra/board-cardhu-panel.c b/arch/arm/mach-tegra/board-cardhu-panel.c
index 80adfc0..4899dee 100644
--- a/arch/arm/mach-tegra/board-cardhu-panel.c
+++ b/arch/arm/mach-tegra/board-cardhu-panel.c
@@ -30,7 +30,7 @@
#include <linux/pwm_backlight.h>
#include <asm/atomic.h>
#include <linux/nvhost.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dc.h>
@@ -707,8 +707,8 @@ static struct tegra_fb_data cardhu_fb_data = {
static struct tegra_fb_data cardhu_hdmi_fb_data = {
.win = 0,
- .xres = 1366,
- .yres = 768,
+ .xres = 640,
+ .yres = 480,
.bits_per_pixel = 32,
.flags = TEGRA_FB_FLIP_ON_PROBE,
};
@@ -734,7 +734,7 @@ static struct tegra_dc_out cardhu_disp2_out = {
};
static struct tegra_dc_platform_data cardhu_disp2_pdata = {
- .flags = 0,
+ .flags = TEGRA_DC_FLAG_ENABLED,
.default_out = &cardhu_disp2_out,
.fb = &cardhu_hdmi_fb_data,
.emc_clk_rate = 300000000,
@@ -1301,6 +1301,11 @@ int __init cardhu_panel_init(void)
IORESOURCE_MEM, "fbmem");
res->start = tegra_fb2_start;
res->end = tegra_fb2_start + tegra_fb2_size - 1;
+
+ /* Copy the bootloader fb to the fb2. */
+ tegra_move_framebuffer(tegra_fb2_start, tegra_bootloader_fb_start,
+ min(tegra_fb2_size, tegra_bootloader_fb_size));
+
if (!err)
err = nvhost_device_register(&cardhu_disp2_device);
#endif
diff --git a/arch/arm/mach-tegra/board-cardhu-pinmux.c b/arch/arm/mach-tegra/board-cardhu-pinmux.c
index 112fcc9..fd0a6ae 100644
--- a/arch/arm/mach-tegra/board-cardhu-pinmux.c
+++ b/arch/arm/mach-tegra/board-cardhu-pinmux.c
@@ -442,8 +442,8 @@ static __initdata struct tegra_pingroup_config cardhu_pinmux_cardhu[] = {
/* Power rails GPIO */
DEFAULT_PINMUX(GMI_CS2_N, NAND, NORMAL, NORMAL, OUTPUT),
- DEFAULT_PINMUX(GMI_RST_N, RSVD3, PULL_UP, TRISTATE, INPUT),
- DEFAULT_PINMUX(GMI_AD15, NAND, PULL_UP, TRISTATE, INPUT),
+ DEFAULT_PINMUX(GMI_RST_N, RSVD3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(GMI_AD15, NAND, PULL_UP, NORMAL, INPUT),
DEFAULT_PINMUX(GMI_CS0_N, GMI, PULL_UP, NORMAL, INPUT),
DEFAULT_PINMUX(GMI_CS1_N, GMI, PULL_UP, TRISTATE, INPUT),
@@ -466,8 +466,8 @@ static __initdata struct tegra_pingroup_config cardhu_pinmux_cardhu_a03[] = {
/* Power rails GPIO */
DEFAULT_PINMUX(PEX_L0_PRSNT_N, PCIE, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(PEX_L0_CLKREQ_N, PCIE, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(PEX_L1_CLKREQ_N, RSVD3, PULL_UP, TRISTATE, INPUT),
- DEFAULT_PINMUX(PEX_L1_PRSNT_N, RSVD3, PULL_UP, TRISTATE, INPUT),
+ DEFAULT_PINMUX(PEX_L1_CLKREQ_N, RSVD3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(PEX_L1_PRSNT_N, RSVD3, PULL_UP, NORMAL, INPUT),
};
static __initdata struct tegra_pingroup_config cardhu_pinmux_e1291_a04[] = {
diff --git a/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c b/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
index afff346..0305ee7 100644
--- a/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
+++ b/arch/arm/mach-tegra/board-cardhu-pm298-power-rails.c
@@ -461,13 +461,13 @@ static struct regulator_consumer_supply fixed_reg_en_vdd_pnl1_supply[] = {
/* CAM1_LDO_EN from AP GPIO KB_ROW6 R06*/
static struct regulator_consumer_supply fixed_reg_cam1_ldo_en_supply[] = {
REGULATOR_SUPPLY("vdd_2v8_cam1", NULL),
- REGULATOR_SUPPLY("vdd", "6-0072"),
+ REGULATOR_SUPPLY("avdd", "6-0072"),
};
/* CAM2_LDO_EN from AP GPIO KB_ROW7 R07*/
static struct regulator_consumer_supply fixed_reg_cam2_ldo_en_supply[] = {
REGULATOR_SUPPLY("vdd_2v8_cam2", NULL),
- REGULATOR_SUPPLY("vdd", "7-0072"),
+ REGULATOR_SUPPLY("avdd", "7-0072"),
};
/* CAM3_LDO_EN from AP GPIO KB_ROW8 S00*/
@@ -505,8 +505,8 @@ static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = {
REGULATOR_SUPPLY("vdd_1v8_cam1", NULL),
REGULATOR_SUPPLY("vdd_1v8_cam2", NULL),
REGULATOR_SUPPLY("vdd_1v8_cam3", NULL),
- REGULATOR_SUPPLY("vdd_i2c", "6-0072"),
- REGULATOR_SUPPLY("vdd_i2c", "7-0072"),
+ REGULATOR_SUPPLY("dvdd", "6-0072"),
+ REGULATOR_SUPPLY("dvdd", "7-0072"),
REGULATOR_SUPPLY("vdd_i2c", "2-0033"),
};
diff --git a/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c b/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
index 5416942..0c55aa4 100644
--- a/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
+++ b/arch/arm/mach-tegra/board-cardhu-pm299-power-rails.c
@@ -181,7 +181,8 @@ static struct regulator_consumer_supply ricoh583_ldo8_supply_0[] = {
RICOH_PDATA_INIT(dc0, 0, 700, 1500, 0, 1, 1, 0, -1, 0, 0, 0,
RICOH583_EXT_PWRREQ2_CONTROL, 0);
-RICOH_PDATA_INIT(dc1, skubit0_0, 700, 1500, 0, 1, 1, 0, -1, 0, 0, 0, 0, 0);
+RICOH_PDATA_INIT(dc1, skubit0_0, 700, 1500, 0, 1, 1, 0, -1, 0, 0, 0,
+ RICOH583_EXT_PWRREQ1_CONTROL, 0);
RICOH_PDATA_INIT(dc2, 0, 900, 2400, 0, 1, 1, 0, -1, 0, 0, 0, 0, 0);
RICOH_PDATA_INIT(dc3, 0, 900, 2400, 0, 1, 1, 0, -1, 0, 0, 0, 0, 0);
@@ -448,13 +449,13 @@ static struct regulator_consumer_supply fixed_reg_en_vdd_pnl1_supply[] = {
/* CAM1_LDO_EN from AP GPIO KB_ROW6 R06*/
static struct regulator_consumer_supply fixed_reg_cam1_ldo_en_supply[] = {
REGULATOR_SUPPLY("vdd_2v8_cam1", NULL),
- REGULATOR_SUPPLY("vdd", "6-0072"),
+ REGULATOR_SUPPLY("avdd", "6-0072"),
};
/* CAM2_LDO_EN from AP GPIO KB_ROW7 R07*/
static struct regulator_consumer_supply fixed_reg_cam2_ldo_en_supply[] = {
REGULATOR_SUPPLY("vdd_2v8_cam2", NULL),
- REGULATOR_SUPPLY("vdd", "7-0072"),
+ REGULATOR_SUPPLY("avdd", "7-0072"),
};
/* CAM3_LDO_EN from AP GPIO KB_ROW8 S00*/
@@ -492,8 +493,8 @@ static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = {
REGULATOR_SUPPLY("vdd_1v8_cam1", NULL),
REGULATOR_SUPPLY("vdd_1v8_cam2", NULL),
REGULATOR_SUPPLY("vdd_1v8_cam3", NULL),
- REGULATOR_SUPPLY("vdd_i2c", "6-0072"),
- REGULATOR_SUPPLY("vdd_i2c", "7-0072"),
+ REGULATOR_SUPPLY("dvdd", "6-0072"),
+ REGULATOR_SUPPLY("dvdd", "7-0072"),
REGULATOR_SUPPLY("vdd_i2c", "2-0033"),
};
@@ -558,13 +559,13 @@ static struct regulator_consumer_supply fixed_reg_en_vddio_vid_oc_supply[] = {
#define FIXED_REG(_id, _var, _name, _in_supply, _always_on, _boot_on, \
_gpio_nr, _active_high, _boot_state, _millivolts) \
FIXED_REG_OD(_id, _var, _name, _in_supply, _always_on, _boot_on, \
- _gpio_nr, _active_high, _boot_state, _millivolts, true)
+ _gpio_nr, _active_high, _boot_state, _millivolts, false)
/* common to most of boards*/
FIXED_REG(0, en_5v_cp, en_5v_cp, NULL, 1, 0, TPS6591X_GPIO_0, true, 1, 5000);
FIXED_REG(1, en_5v0, en_5v0, NULL, 0, 0, TPS6591X_GPIO_4, true, 0, 5000);
FIXED_REG(2, en_ddr, en_ddr, NULL, 0, 0, TPS6591X_GPIO_3, true, 1, 1500);
-FIXED_REG(3, en_3v3_sys, en_3v3_sys, NULL, 0, 0, TPS6591X_GPIO_1, true, 0, 3300);
+FIXED_REG(3, en_3v3_sys, en_3v3_sys, NULL, 0, 0, TPS6591X_GPIO_1, true, 1, 3300);
FIXED_REG(4, en_vdd_bl, en_vdd_bl, NULL, 0, 0, TEGRA_GPIO_PK3, true, 1, 5000);
FIXED_REG(5, en_3v3_modem, en_3v3_modem, NULL, 1, 0, TEGRA_GPIO_PD6, true, 1, 3300);
FIXED_REG(6, en_vdd_pnl1, en_vdd_pnl1, FIXED_SUPPLY(en_3v3_sys), 0, 0, TEGRA_GPIO_PL4, true, 1, 3300);
diff --git a/arch/arm/mach-tegra/board-cardhu-power.c b/arch/arm/mach-tegra/board-cardhu-power.c
index fada59b..79d8d61 100644
--- a/arch/arm/mach-tegra/board-cardhu-power.c
+++ b/arch/arm/mach-tegra/board-cardhu-power.c
@@ -191,7 +191,7 @@ static struct regulator_consumer_supply tps6591x_ldo8_supply_0[] = {
TPS_PDATA_INIT(vdd1, skubit0_0, 600, 1500, 0, 1, 1, 0, -1, 0, 0, EXT_CTRL_SLEEP_OFF, 0);
TPS_PDATA_INIT(vdd1, skubit0_1, 600, 1500, 0, 1, 1, 0, -1, 0, 0, EXT_CTRL_SLEEP_OFF, 0);
-TPS_PDATA_INIT(vdd2, 0, 600, 1500, 0, 1, 1, 0, -1, 0, 0, 0, 0);
+TPS_PDATA_INIT(vdd2, 0, 600, 1500, 0, 0, 1, 0, -1, 0, 0, 0, 0);
TPS_PDATA_INIT(vddctrl, 0, 600, 1400, 0, 1, 1, 0, -1, 0, 0, EXT_CTRL_EN1, 0);
TPS_PDATA_INIT(vio, 0, 1500, 3300, 0, 1, 1, 0, -1, 0, 0, 0, 0);
@@ -486,7 +486,8 @@ int __init cardhu_regulator_init(void)
/* E1291-A04/A05: Enable DEV_SLP and enable sleep on GPIO2 */
if ((board_info.board_id == BOARD_E1291) &&
((board_info.fab == BOARD_FAB_A04) ||
- (board_info.fab == BOARD_FAB_A05))) {
+ (board_info.fab == BOARD_FAB_A05) ||
+ (board_info.fab == BOARD_FAB_A07))) {
tps_platform.dev_slp_en = true;
tps_platform.gpio_init_data = tps_gpio_pdata_e1291_a04;
tps_platform.num_gpioinit_data =
@@ -602,13 +603,13 @@ static struct regulator_consumer_supply fixed_reg_en_vdd_pnl1_supply[] = {
/* CAM1_LDO_EN from AP GPIO KB_ROW6 R06*/
static struct regulator_consumer_supply fixed_reg_cam1_ldo_en_supply[] = {
REGULATOR_SUPPLY("vdd_2v8_cam1", NULL),
- REGULATOR_SUPPLY("vdd", "6-0072"),
+ REGULATOR_SUPPLY("avdd", "6-0072"),
};
/* CAM2_LDO_EN from AP GPIO KB_ROW7 R07*/
static struct regulator_consumer_supply fixed_reg_cam2_ldo_en_supply[] = {
REGULATOR_SUPPLY("vdd_2v8_cam2", NULL),
- REGULATOR_SUPPLY("vdd", "7-0072"),
+ REGULATOR_SUPPLY("avdd", "7-0072"),
};
/* CAM3_LDO_EN from AP GPIO KB_ROW8 S00*/
@@ -646,8 +647,8 @@ static struct regulator_consumer_supply fixed_reg_en_1v8_cam_supply[] = {
REGULATOR_SUPPLY("vdd_1v8_cam1", NULL),
REGULATOR_SUPPLY("vdd_1v8_cam2", NULL),
REGULATOR_SUPPLY("vdd_1v8_cam3", NULL),
- REGULATOR_SUPPLY("vdd_i2c", "6-0072"),
- REGULATOR_SUPPLY("vdd_i2c", "7-0072"),
+ REGULATOR_SUPPLY("dvdd", "6-0072"),
+ REGULATOR_SUPPLY("dvdd", "7-0072"),
REGULATOR_SUPPLY("vdd_i2c", "2-0033"),
};
@@ -1027,7 +1028,8 @@ int __init cardhu_fixed_regulator_init(void)
nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e1291_a03);
fixed_reg_devs = fixed_reg_devs_e1291_a03;
} else if ((board_info.fab == BOARD_FAB_A04) ||
- (board_info.fab == BOARD_FAB_A05)) {
+ (board_info.fab == BOARD_FAB_A05) ||
+ (board_info.fab == BOARD_FAB_A07)) {
nfixreg_devs = ARRAY_SIZE(fixed_reg_devs_e1291_a04);
fixed_reg_devs = fixed_reg_devs_e1291_a04;
} else {
@@ -1151,17 +1153,6 @@ int __init cardhu_suspend_init(void)
return 0;
}
-static struct tegra_tsensor_pmu_data tpdata = {
- .poweroff_reg_addr = 0x3F,
- .poweroff_reg_data = 0x80,
- .reset_tegra = 1,
- .controller_type = 0,
- .i2c_controller_id = 4,
- .pinmux = 0,
- .pmu_16bit_ops = 0,
- .pmu_i2c_addr = 0x2D,
-};
-
#ifdef CONFIG_TEGRA_EDP_LIMITS
int __init cardhu_edp_init(void)
diff --git a/arch/arm/mach-tegra/board-cardhu-sdhci.c b/arch/arm/mach-tegra/board-cardhu-sdhci.c
index fddf01f..c4e631dd 100644
--- a/arch/arm/mach-tegra/board-cardhu-sdhci.c
+++ b/arch/arm/mach-tegra/board-cardhu-sdhci.c
@@ -2,7 +2,7 @@
* arch/arm/mach-tegra/board-harmony-sdhci.c
*
* Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2011 NVIDIA Corporation.
+ * Copyright (C) 2011-2012 NVIDIA Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -63,7 +63,7 @@ static struct resource wifi_resource[] = {
},
};
-static struct platform_device cardhu_wifi_device = {
+static struct platform_device broadcom_wifi_device = {
.name = "bcm4329_wlan",
.id = 1,
.num_resources = 1,
@@ -73,6 +73,15 @@ static struct platform_device cardhu_wifi_device = {
},
};
+static struct platform_device marvell_wifi_device = {
+ .name = "mrvl8797_wlan",
+ .id = 1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &cardhu_wifi_control,
+ },
+};
+
static struct resource sdhci_resource0[] = {
[0] = {
.start = INT_SDMMC1,
@@ -112,6 +121,7 @@ static struct resource sdhci_resource3[] = {
},
};
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
static struct embedded_sdio_data embedded_sdio_data2 = {
.cccr = {
.sdio_vsn = 2,
@@ -126,18 +136,25 @@ static struct embedded_sdio_data embedded_sdio_data2 = {
.device = 0x4329,
},
};
+#endif
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
.mmc_data = {
.register_status_notify = cardhu_wifi_status_register,
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
.embedded_sdio = &embedded_sdio_data2,
- .built_in = 1,
+#endif
+ .built_in = 0,
},
+#ifndef CONFIG_MMC_EMBEDDED_SDIO
+ .pm_flags = MMC_PM_KEEP_POWER,
+#endif
.cd_gpio = -1,
.wp_gpio = -1,
.power_gpio = -1,
-/* .tap_delay = 6,
- .is_voltage_switch_supported = false,
+ .tap_delay = 0x0F,
+ .ddr_clk_limit = 41000000,
+/* .is_voltage_switch_supported = false,
.vdd_rail_name = NULL,
.slot_rail_name = NULL,
.vdd_max_uv = -1,
@@ -150,8 +167,9 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
.cd_gpio = CARDHU_SD_CD,
.wp_gpio = CARDHU_SD_WP,
.power_gpio = -1,
-/* .tap_delay = 6,
- .is_voltage_switch_supported = true,
+ .tap_delay = 0x0F,
+ .ddr_clk_limit = 41000000,
+/* .is_voltage_switch_supported = true,
.vdd_rail_name = "vddio_sdmmc1",
.slot_rail_name = "vddio_sd_slot",
.vdd_max_uv = 3320000,
@@ -166,11 +184,11 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
.power_gpio = -1,
.is_8bit = 1,
.tap_delay = 0x0F,
+ .ddr_clk_limit = 41000000,
.mmc_data = {
.built_in = 1,
}
-/* .tap_delay = 6,
- .is_voltage_switch_supported = false,
+/* .is_voltage_switch_supported = false,
.vdd_rail_name = NULL,
.slot_rail_name = NULL,
.vdd_max_uv = -1,
@@ -250,6 +268,7 @@ static int cardhu_wifi_reset(int on)
static int __init cardhu_wifi_init(void)
{
int rc;
+ int commchip_id = tegra_get_commchip_id();
rc = gpio_request(CARDHU_WLAN_PWR, "wlan_power");
if (rc)
@@ -275,10 +294,28 @@ static int __init cardhu_wifi_init(void)
if (rc)
pr_err("WLAN_WOW gpio direction configuration failed:%d\n", rc);
- platform_device_register(&cardhu_wifi_device);
+ if (commchip_id == COMMCHIP_MARVELL_SD8797)
+ platform_device_register(&marvell_wifi_device);
+ else
+ platform_device_register(&broadcom_wifi_device);
+
return 0;
}
+#ifdef CONFIG_TEGRA_PREPOWER_WIFI
+static int __init cardhu_wifi_prepower(void)
+{
+ if (!machine_is_cardhu())
+ return 0;
+
+ cardhu_wifi_power(1);
+
+ return 0;
+}
+
+subsys_initcall_sync(cardhu_wifi_prepower);
+#endif
+
int __init cardhu_sdhci_init(void)
{
struct board_info board_info;
diff --git a/arch/arm/mach-tegra/board-cardhu-sensors.c b/arch/arm/mach-tegra/board-cardhu-sensors.c
index 0f7d2f9..66b3c9d 100644
--- a/arch/arm/mach-tegra/board-cardhu-sensors.c
+++ b/arch/arm/mach-tegra/board-cardhu-sensors.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-cardhu-sensors.c
*
- * Copyright (c) 2010-2011, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2010-2012, NVIDIA CORPORATION, All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -40,6 +40,7 @@
#include <mach/fb.h>
#include <mach/gpio.h>
#include <media/ov5650.h>
+#include <media/ov5640.h>
#include <media/ov14810.h>
#include <media/ov2710.h>
#include <media/tps61050.h>
@@ -464,6 +465,86 @@ struct ov2710_platform_data cardhu_ov2710_data = {
.power_off = cardhu_ov2710_power_off,
};
+static int cardhu_ov5640_power_on(void)
+{
+ /* CSI-B and front sensor are muxed on cardhu */
+ gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1);
+
+ /* Boards E1198 and E1291 are of Cardhu personality
+ * and donot have TCA6416 exp for camera */
+ if ((board_info.board_id == BOARD_E1198) ||
+ (board_info.board_id == BOARD_E1291)) {
+
+ gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
+ gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
+ gpio_direction_output(CAM3_POWER_DWN_GPIO, 0);
+ mdelay(10);
+
+ if (cardhu_vdd_cam3 == NULL) {
+ cardhu_vdd_cam3 = regulator_get(NULL, "vdd_cam3");
+ if (WARN_ON(IS_ERR(cardhu_vdd_cam3))) {
+ pr_err("%s: couldn't get regulator vdd_cam3: %ld\n",
+ __func__, PTR_ERR(cardhu_vdd_cam3));
+ goto reg_alloc_fail;
+ }
+ }
+ regulator_enable(cardhu_vdd_cam3);
+ }
+
+ /* Enable VDD_1V8_Cam3 */
+ if (cardhu_1v8_cam3 == NULL) {
+ cardhu_1v8_cam3 = regulator_get(NULL, "vdd_1v8_cam3");
+ if (WARN_ON(IS_ERR(cardhu_1v8_cam3))) {
+ pr_err("%s: couldn't get regulator vdd_1v8_cam3: %ld\n",
+ __func__, PTR_ERR(cardhu_1v8_cam3));
+ goto reg_alloc_fail;
+ }
+ }
+ regulator_enable(cardhu_1v8_cam3);
+ mdelay(5);
+
+ return 0;
+
+reg_alloc_fail:
+ if (cardhu_1v8_cam3) {
+ regulator_put(cardhu_1v8_cam3);
+ cardhu_1v8_cam3 = NULL;
+ }
+ if (cardhu_vdd_cam3) {
+ regulator_put(cardhu_vdd_cam3);
+ cardhu_vdd_cam3 = NULL;
+ }
+
+ return -ENODEV;
+}
+
+static int cardhu_ov5640_power_off(void)
+{
+ /* CSI-B and front sensor are muxed on cardhu */
+ gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1);
+
+ /* Boards E1198 and E1291 are of Cardhu personality
+ * and donot have TCA6416 exp for camera */
+ if ((board_info.board_id == BOARD_E1198) ||
+ (board_info.board_id == BOARD_E1291)) {
+ gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
+ gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
+ gpio_direction_output(CAM3_POWER_DWN_GPIO, 1);
+ }
+
+ if (cardhu_1v8_cam3)
+ regulator_disable(cardhu_1v8_cam3);
+ if (cardhu_vdd_cam3)
+ regulator_disable(cardhu_vdd_cam3);
+
+ return 0;
+}
+
+struct ov5640_platform_data cardhu_ov5640_data = {
+ .power_on = cardhu_ov5640_power_on,
+ .power_off = cardhu_ov5640_power_off,
+};
+
static const struct i2c_board_info cardhu_i2c3_board_info[] = {
{
I2C_BOARD_INFO("pca9546", 0x70),
@@ -471,34 +552,56 @@ static const struct i2c_board_info cardhu_i2c3_board_info[] = {
},
};
+
+static struct nvc_gpio_pdata sh532u_gpio_pdata[] = {
+ { SH532U_GPIO_RESET, TEGRA_GPIO_PBB0, false, 0, },
+};
+
static struct sh532u_platform_data sh532u_left_pdata = {
+ .cfg = NVC_CFG_NODEV,
.num = 1,
.sync = 2,
.dev_name = "focuser",
- .gpio_reset = TEGRA_GPIO_PBB0,
+ .gpio_count = ARRAY_SIZE(sh532u_gpio_pdata),
+ .gpio = sh532u_gpio_pdata,
};
static struct sh532u_platform_data sh532u_right_pdata = {
+ .cfg = NVC_CFG_NODEV,
.num = 2,
.sync = 1,
.dev_name = "focuser",
- .gpio_reset = TEGRA_GPIO_PBB0,
+ .gpio_count = ARRAY_SIZE(sh532u_gpio_pdata),
+ .gpio = sh532u_gpio_pdata,
+};
+
+static struct nvc_gpio_pdata pm269_sh532u_left_gpio_pdata[] = {
+ { SH532U_GPIO_RESET, CAM1_RST_L_GPIO, false, 0, },
};
static struct sh532u_platform_data pm269_sh532u_left_pdata = {
+ .cfg = 0,
.num = 1,
.sync = 2,
.dev_name = "focuser",
- .gpio_reset = CAM1_RST_L_GPIO,
+ .gpio_count = ARRAY_SIZE(pm269_sh532u_left_gpio_pdata),
+ .gpio = pm269_sh532u_left_gpio_pdata,
+};
+
+static struct nvc_gpio_pdata pm269_sh532u_right_gpio_pdata[] = {
+ { SH532U_GPIO_RESET, CAM2_RST_L_GPIO, false, 0, },
};
static struct sh532u_platform_data pm269_sh532u_right_pdata = {
+ .cfg = 0,
.num = 2,
.sync = 1,
.dev_name = "focuser",
- .gpio_reset = CAM2_RST_L_GPIO,
+ .gpio_count = ARRAY_SIZE(pm269_sh532u_right_gpio_pdata),
+ .gpio = pm269_sh532u_right_gpio_pdata,
};
+
static struct nvc_torch_pin_state cardhu_tps61050_pinstate = {
.mask = 0x0008, /*VGP3*/
.values = 0x0008,
@@ -565,6 +668,10 @@ static struct i2c_board_info cardhu_i2c8_board_info[] = {
I2C_BOARD_INFO("ov2710", 0x36),
.platform_data = &cardhu_ov2710_data,
},
+ {
+ I2C_BOARD_INFO("ov5640", 0x3C),
+ .platform_data = &cardhu_ov5640_data,
+ },
};
static int nct_get_temp(void *_data, long *temp)
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index 339011e..9083828 100644
--- a/arch/arm/mach-tegra/board-cardhu.c
+++ b/arch/arm/mach-tegra/board-cardhu.c
@@ -62,6 +62,7 @@
#include "board.h"
#include "clock.h"
#include "board-cardhu.h"
+#include "board-touch.h"
#include "devices.h"
#include "gpio-names.h"
#include "fuse.h"
@@ -71,19 +72,17 @@
/* All units are in millicelsius */
static struct tegra_thermal_data thermal_data = {
- .temp_throttle = 85000,
.temp_shutdown = 90000,
.temp_offset = TDIODE_OFFSET, /* temps based on tdiode */
#ifdef CONFIG_TEGRA_EDP_LIMITS
.edp_offset = TDIODE_OFFSET, /* edp based on tdiode */
.hysteresis_edp = 3000,
#endif
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
+ .temp_throttle = 85000,
.tc1 = 0,
.tc2 = 1,
.passive_delay = 2000,
-#else
- .hysteresis_throttle = 1000,
#endif
};
@@ -227,7 +226,7 @@ static struct tegra_i2c_platform_data cardhu_i2c1_platform_data = {
static struct tegra_i2c_platform_data cardhu_i2c2_platform_data = {
.adapter_nr = 1,
.bus_count = 1,
- .bus_clk_rate = { 100000, 0 },
+ .bus_clk_rate = { 400000, 0 },
.is_clkon_always = true,
.scl_gpio = {TEGRA_GPIO_PT5, 0},
.sda_gpio = {TEGRA_GPIO_PT6, 0},
@@ -574,6 +573,10 @@ static struct platform_device *cardhu_spi_devices[] __initdata = {
&tegra_spi_device4,
};
+static struct platform_device *touch_spi_device[] __initdata = {
+ &tegra_spi_device1,
+};
+
struct spi_clk_parent spi_parent_clk[] = {
[0] = {.name = "pll_p"},
#ifndef CONFIG_TEGRA_PLLM_RESTRICTED
@@ -595,9 +598,10 @@ static void __init cardhu_spi_init(void)
{
int i;
struct clk *c;
- struct board_info board_info;
+ struct board_info board_info, display_board_info;
tegra_get_board_info(&board_info);
+ tegra_get_display_board_info(&display_board_info);
for (i = 0; i < ARRAY_SIZE(spi_parent_clk); ++i) {
c = tegra_get_clock_by_name(spi_parent_clk[i].name);
@@ -615,6 +619,10 @@ static void __init cardhu_spi_init(void)
platform_add_devices(cardhu_spi_devices,
ARRAY_SIZE(cardhu_spi_devices));
+ if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
+ platform_add_devices(touch_spi_device,
+ ARRAY_SIZE(touch_spi_device));
+ }
if (board_info.board_id == BOARD_E1198) {
tegra_spi_device2.dev.platform_data = &cardhu_spi_pdata;
platform_device_register(&tegra_spi_device2);
@@ -821,30 +829,43 @@ static struct i2c_board_info __initdata atmel_i2c_info[] = {
}
};
+static __initdata struct tegra_clk_init_table spi_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "sbc1", "pll_p", 52000000, true},
+ { NULL, NULL, 0, 0},
+};
+
static int __init cardhu_touch_init(void)
{
struct board_info BoardInfo;
- tegra_gpio_enable(TEGRA_GPIO_PH4);
- tegra_gpio_enable(TEGRA_GPIO_PH6);
-
- gpio_request(TEGRA_GPIO_PH4, "atmel-irq");
- gpio_direction_input(TEGRA_GPIO_PH4);
+ tegra_get_display_board_info(&BoardInfo);
+ if (BoardInfo.board_id == BOARD_DISPLAY_PM313) {
+ tegra_clk_init_from_table(spi_clk_init_table);
- gpio_request(TEGRA_GPIO_PH6, "atmel-reset");
- gpio_direction_output(TEGRA_GPIO_PH6, 0);
- msleep(1);
- gpio_set_value(TEGRA_GPIO_PH6, 1);
- msleep(100);
+ touch_init_raydium(TEGRA_GPIO_PH4, TEGRA_GPIO_PH6, 2);
+ } else {
+ tegra_gpio_enable(TEGRA_GPIO_PH4);
+ tegra_gpio_enable(TEGRA_GPIO_PH6);
+
+ gpio_request(TEGRA_GPIO_PH4, "atmel-irq");
+ gpio_direction_input(TEGRA_GPIO_PH4);
+
+ gpio_request(TEGRA_GPIO_PH6, "atmel-reset");
+ gpio_direction_output(TEGRA_GPIO_PH6, 0);
+ msleep(1);
+ gpio_set_value(TEGRA_GPIO_PH6, 1);
+ msleep(100);
+
+ tegra_get_board_info(&BoardInfo);
+ if ((BoardInfo.sku & SKU_TOUCH_MASK) == SKU_TOUCH_2000) {
+ atmel_mxt_info.config = config_sku2000;
+ atmel_mxt_info.config_crc = MXT_CONFIG_CRC_SKU2000;
+ }
- tegra_get_board_info(&BoardInfo);
- if ((BoardInfo.sku & SKU_TOUCH_MASK) == SKU_TOUCH_2000) {
- atmel_mxt_info.config = config_sku2000;
- atmel_mxt_info.config_crc = MXT_CONFIG_CRC_SKU2000;
+ i2c_register_board_info(1, atmel_i2c_info, 1);
}
- i2c_register_board_info(1, atmel_i2c_info, 1);
-
return 0;
}
diff --git a/arch/arm/mach-tegra/board-cardhu.h b/arch/arm/mach-tegra/board-cardhu.h
index ba2a0d0..27d9e47 100644
--- a/arch/arm/mach-tegra/board-cardhu.h
+++ b/arch/arm/mach-tegra/board-cardhu.h
@@ -76,6 +76,8 @@
#define BOARD_FAB_A03 0x3
#define BOARD_FAB_A04 0x4
#define BOARD_FAB_A05 0x5
+#define BOARD_FAB_A06 0x6
+#define BOARD_FAB_A07 0x7
/* Display Board ID */
#define BOARD_DISPLAY_PM313 0x030D
diff --git a/arch/arm/mach-tegra/board-enterprise-memory.c b/arch/arm/mach-tegra/board-enterprise-memory.c
index fca1a08..36a8264 100644
--- a/arch/arm/mach-tegra/board-enterprise-memory.c
+++ b/arch/arm/mach-tegra/board-enterprise-memory.c
@@ -24,7 +24,7 @@
#include "board.h"
-static const struct tegra_emc_table enterprise_emc_tables_h5tc2g[] = {
+static const struct tegra_emc_table enterprise_emc_tables_kmmll0_a02[] = {
{
0x32, /* Rev 3.2 */
12750, /* SDRAM frequency */
@@ -717,7 +717,7 @@ static const struct tegra_emc_table enterprise_emc_tables_h5tc2g[] = {
0x00000000, /* EMC_CTT_DURATION */
0x80000ce6, /* EMC_DYN_SELF_REF_CONTROL */
0x00000006, /* MC_EMEM_ARB_CFG */
- 0x80000048, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0xc0000048, /* MC_EMEM_ARB_OUTSTANDING_REQ */
0x00000002, /* MC_EMEM_ARB_TIMING_RCD */
0x00000003, /* MC_EMEM_ARB_TIMING_RP */
0x0000000c, /* MC_EMEM_ARB_TIMING_RC */
@@ -747,6 +747,729 @@ static const struct tegra_emc_table enterprise_emc_tables_h5tc2g[] = {
},
};
+static const struct tegra_emc_table enterprise_emc_tables_kmkts0_a03[] = {
+ {
+ 0x32, /* Rev 3.2 */
+ 12750, /* SDRAM frequency */
+ {
+ 0x00000000, /* EMC_RC */
+ 0x00000001, /* EMC_RFC */
+ 0x00000002, /* EMC_RAS */
+ 0x00000002, /* EMC_RP */
+ 0x00000004, /* EMC_R2W */
+ 0x00000004, /* EMC_W2R */
+ 0x00000001, /* EMC_R2P */
+ 0x00000005, /* EMC_W2P */
+ 0x00000002, /* EMC_RD_RCD */
+ 0x00000002, /* EMC_WR_RCD */
+ 0x00000001, /* EMC_RRD */
+ 0x00000001, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000001, /* EMC_WDV */
+ 0x00000003, /* EMC_QUSE */
+ 0x00000001, /* EMC_QRST */
+ 0x0000000b, /* EMC_QSAFE */
+ 0x0000000a, /* EMC_RDV */
+ 0x0000002f, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x0000000b, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000001, /* EMC_PDEX2WR */
+ 0x00000001, /* EMC_PDEX2RD */
+ 0x00000002, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x00000001, /* EMC_AR2PDEN */
+ 0x00000007, /* EMC_RW2PDEN */
+ 0x00000002, /* EMC_TXSR */
+ 0x00000002, /* EMC_TXSRDLL */
+ 0x00000003, /* EMC_TCKE */
+ 0x00000008, /* EMC_TFAW */
+ 0x00000004, /* EMC_TRPAB */
+ 0x00000001, /* EMC_TCLKSTABLE */
+ 0x00000002, /* EMC_TCLKSTOP */
+ 0x00000036, /* EMC_TREFBW */
+ 0x00000004, /* EMC_QUSE_EXTRA */
+ 0x00000006, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00004282, /* EMC_FBIO_CFG5 */
+ 0x007800a4, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
+ 0x00100220, /* EMC_XM2CMDPADCTRL */
+ 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
+ 0x00000000, /* EMC_XM2DQPADCTRL2 */
+ 0x77ffc004, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f008, /* EMC_XM2COMPPADCTRL */
+ 0x00000000, /* EMC_XM2VTTGENPADCTRL */
+ 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x08000068, /* EMC_XM2QUSEPADCTRL */
+ 0x08000000, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00064000, /* EMC_ZCAL_INTERVAL */
+ 0x00000009, /* EMC_ZCAL_WAIT_CNT */
+ 0x00090009, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x80000164, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x00050001, /* MC_EMEM_ARB_CFG */
+ 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
+ 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
+ 0x77230303, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xe0000000, /* EMC_FBIO_SPARE */
+ 0xff00ff00, /* EMC_CFG_RSV */
+ },
+ 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000001, /* EMC_CFG.PERIODIC_QRST */
+ 0x00000000, /* Mode Register 0 */
+ 0x00010022, /* Mode Register 1 */
+ 0x00020001, /* Mode Register 2 */
+ 0x00000001, /* EMC_CFG.DYN_SELF_REF */
+ },
+ {
+ 0x32, /* Rev 3.2 */
+ 25500, /* SDRAM frequency */
+ {
+ 0x00000001, /* EMC_RC */
+ 0x00000003, /* EMC_RFC */
+ 0x00000002, /* EMC_RAS */
+ 0x00000002, /* EMC_RP */
+ 0x00000004, /* EMC_R2W */
+ 0x00000004, /* EMC_W2R */
+ 0x00000001, /* EMC_R2P */
+ 0x00000005, /* EMC_W2P */
+ 0x00000002, /* EMC_RD_RCD */
+ 0x00000002, /* EMC_WR_RCD */
+ 0x00000001, /* EMC_RRD */
+ 0x00000001, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000001, /* EMC_WDV */
+ 0x00000003, /* EMC_QUSE */
+ 0x00000001, /* EMC_QRST */
+ 0x0000000b, /* EMC_QSAFE */
+ 0x0000000a, /* EMC_RDV */
+ 0x00000060, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x00000018, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000001, /* EMC_PDEX2WR */
+ 0x00000001, /* EMC_PDEX2RD */
+ 0x00000002, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x00000001, /* EMC_AR2PDEN */
+ 0x00000007, /* EMC_RW2PDEN */
+ 0x00000004, /* EMC_TXSR */
+ 0x00000004, /* EMC_TXSRDLL */
+ 0x00000003, /* EMC_TCKE */
+ 0x00000008, /* EMC_TFAW */
+ 0x00000004, /* EMC_TRPAB */
+ 0x00000001, /* EMC_TCLKSTABLE */
+ 0x00000002, /* EMC_TCLKSTOP */
+ 0x0000006b, /* EMC_TREFBW */
+ 0x00000004, /* EMC_QUSE_EXTRA */
+ 0x00000006, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00004282, /* EMC_FBIO_CFG5 */
+ 0x007800a4, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
+ 0x00100220, /* EMC_XM2CMDPADCTRL */
+ 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
+ 0x00000000, /* EMC_XM2DQPADCTRL2 */
+ 0x77ffc004, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f008, /* EMC_XM2COMPPADCTRL */
+ 0x00000000, /* EMC_XM2VTTGENPADCTRL */
+ 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x08000068, /* EMC_XM2QUSEPADCTRL */
+ 0x08000000, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00064000, /* EMC_ZCAL_INTERVAL */
+ 0x0000000a, /* EMC_ZCAL_WAIT_CNT */
+ 0x00090009, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x800001c5, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x00020001, /* MC_EMEM_ARB_CFG */
+ 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
+ 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
+ 0x73e30303, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xe0000000, /* EMC_FBIO_SPARE */
+ 0xff00ff00, /* EMC_CFG_RSV */
+ },
+ 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000001, /* EMC_CFG.PERIODIC_QRST */
+ 0x00000000, /* Mode Register 0 */
+ 0x00010022, /* Mode Register 1 */
+ 0x00020001, /* Mode Register 2 */
+ 0x00000001, /* EMC_CFG.DYN_SELF_REF */
+ },
+ {
+ 0x32, /* Rev 3.2 */
+ 51000, /* SDRAM frequency */
+ {
+ 0x00000003, /* EMC_RC */
+ 0x00000006, /* EMC_RFC */
+ 0x00000002, /* EMC_RAS */
+ 0x00000002, /* EMC_RP */
+ 0x00000004, /* EMC_R2W */
+ 0x00000004, /* EMC_W2R */
+ 0x00000001, /* EMC_R2P */
+ 0x00000005, /* EMC_W2P */
+ 0x00000002, /* EMC_RD_RCD */
+ 0x00000002, /* EMC_WR_RCD */
+ 0x00000001, /* EMC_RRD */
+ 0x00000001, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000001, /* EMC_WDV */
+ 0x00000003, /* EMC_QUSE */
+ 0x00000001, /* EMC_QRST */
+ 0x0000000b, /* EMC_QSAFE */
+ 0x0000000a, /* EMC_RDV */
+ 0x000000c0, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x00000030, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000001, /* EMC_PDEX2WR */
+ 0x00000001, /* EMC_PDEX2RD */
+ 0x00000002, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x00000001, /* EMC_AR2PDEN */
+ 0x00000007, /* EMC_RW2PDEN */
+ 0x00000008, /* EMC_TXSR */
+ 0x00000008, /* EMC_TXSRDLL */
+ 0x00000003, /* EMC_TCKE */
+ 0x00000008, /* EMC_TFAW */
+ 0x00000004, /* EMC_TRPAB */
+ 0x00000001, /* EMC_TCLKSTABLE */
+ 0x00000002, /* EMC_TCLKSTOP */
+ 0x000000d5, /* EMC_TREFBW */
+ 0x00000004, /* EMC_QUSE_EXTRA */
+ 0x00000006, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00004282, /* EMC_FBIO_CFG5 */
+ 0x007800a4, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
+ 0x00100220, /* EMC_XM2CMDPADCTRL */
+ 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
+ 0x00000000, /* EMC_XM2DQPADCTRL2 */
+ 0x77ffc004, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f008, /* EMC_XM2COMPPADCTRL */
+ 0x00000000, /* EMC_XM2VTTGENPADCTRL */
+ 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x08000068, /* EMC_XM2QUSEPADCTRL */
+ 0x08000000, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00064000, /* EMC_ZCAL_INTERVAL */
+ 0x00000013, /* EMC_ZCAL_WAIT_CNT */
+ 0x00090009, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x80000287, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x00010001, /* MC_EMEM_ARB_CFG */
+ 0xc000000a, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
+ 0x00060402, /* MC_EMEM_ARB_DA_COVERS */
+ 0x72c30303, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xe0000000, /* EMC_FBIO_SPARE */
+ 0xff00ff00, /* EMC_CFG_RSV */
+ },
+ 0x00000009, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000001, /* EMC_CFG.PERIODIC_QRST */
+ 0x00000000, /* Mode Register 0 */
+ 0x00010022, /* Mode Register 1 */
+ 0x00020001, /* Mode Register 2 */
+ 0x00000001, /* EMC_CFG.DYN_SELF_REF */
+ },
+ {
+ 0x32, /* Rev 3.2 */
+ 102000, /* SDRAM frequency */
+ {
+ 0x00000006, /* EMC_RC */
+ 0x0000000d, /* EMC_RFC */
+ 0x00000004, /* EMC_RAS */
+ 0x00000002, /* EMC_RP */
+ 0x00000004, /* EMC_R2W */
+ 0x00000004, /* EMC_W2R */
+ 0x00000002, /* EMC_R2P */
+ 0x00000005, /* EMC_W2P */
+ 0x00000002, /* EMC_RD_RCD */
+ 0x00000002, /* EMC_WR_RCD */
+ 0x00000001, /* EMC_RRD */
+ 0x00000001, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000001, /* EMC_WDV */
+ 0x00000003, /* EMC_QUSE */
+ 0x00000001, /* EMC_QRST */
+ 0x0000000b, /* EMC_QSAFE */
+ 0x0000000a, /* EMC_RDV */
+ 0x00000181, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x00000060, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000001, /* EMC_PDEX2WR */
+ 0x00000001, /* EMC_PDEX2RD */
+ 0x00000002, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x00000001, /* EMC_AR2PDEN */
+ 0x00000007, /* EMC_RW2PDEN */
+ 0x0000000f, /* EMC_TXSR */
+ 0x0000000f, /* EMC_TXSRDLL */
+ 0x00000003, /* EMC_TCKE */
+ 0x00000008, /* EMC_TFAW */
+ 0x00000004, /* EMC_TRPAB */
+ 0x00000001, /* EMC_TCLKSTABLE */
+ 0x00000002, /* EMC_TCLKSTOP */
+ 0x000001a9, /* EMC_TREFBW */
+ 0x00000004, /* EMC_QUSE_EXTRA */
+ 0x00000006, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00004282, /* EMC_FBIO_CFG5 */
+ 0x007800a4, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
+ 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
+ 0x00100220, /* EMC_XM2CMDPADCTRL */
+ 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
+ 0x00000000, /* EMC_XM2DQPADCTRL2 */
+ 0x77ffc004, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f008, /* EMC_XM2COMPPADCTRL */
+ 0x00000000, /* EMC_XM2VTTGENPADCTRL */
+ 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x08000068, /* EMC_XM2QUSEPADCTRL */
+ 0x08000000, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00000000, /* EMC_ZCAL_INTERVAL */
+ 0x0000000a, /* EMC_ZCAL_WAIT_CNT */
+ 0x00090009, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x8000040b, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x00000001, /* MC_EMEM_ARB_CFG */
+ 0xc0000013, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_RC */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x02020001, /* MC_EMEM_ARB_DA_TURNS */
+ 0x00060403, /* MC_EMEM_ARB_DA_COVERS */
+ 0x72430504, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xe0000000, /* EMC_FBIO_SPARE */
+ 0xff00ff00, /* EMC_CFG_RSV */
+ },
+ 0x0000000a, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000001, /* EMC_CFG.PERIODIC_QRST */
+ 0x00000000, /* Mode Register 0 */
+ 0x00010022, /* Mode Register 1 */
+ 0x00020001, /* Mode Register 2 */
+ 0x00000001, /* EMC_CFG.DYN_SELF_REF */
+ },
+ {
+ 0x32, /* Rev 3.2 */
+ 204000, /* SDRAM frequency */
+ {
+ 0x0000000c, /* EMC_RC */
+ 0x0000001a, /* EMC_RFC */
+ 0x00000008, /* EMC_RAS */
+ 0x00000003, /* EMC_RP */
+ 0x00000005, /* EMC_R2W */
+ 0x00000004, /* EMC_W2R */
+ 0x00000002, /* EMC_R2P */
+ 0x00000006, /* EMC_W2P */
+ 0x00000003, /* EMC_RD_RCD */
+ 0x00000003, /* EMC_WR_RCD */
+ 0x00000002, /* EMC_RRD */
+ 0x00000002, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000001, /* EMC_WDV */
+ 0x00000003, /* EMC_QUSE */
+ 0x00000001, /* EMC_QRST */
+ 0x0000000c, /* EMC_QSAFE */
+ 0x0000000b, /* EMC_RDV */
+ 0x00000303, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x000000c0, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000001, /* EMC_PDEX2WR */
+ 0x00000001, /* EMC_PDEX2RD */
+ 0x00000003, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x00000001, /* EMC_AR2PDEN */
+ 0x00000007, /* EMC_RW2PDEN */
+ 0x0000001d, /* EMC_TXSR */
+ 0x0000001d, /* EMC_TXSRDLL */
+ 0x00000004, /* EMC_TCKE */
+ 0x0000000b, /* EMC_TFAW */
+ 0x00000005, /* EMC_TRPAB */
+ 0x00000001, /* EMC_TCLKSTABLE */
+ 0x00000002, /* EMC_TCLKSTOP */
+ 0x00000351, /* EMC_TREFBW */
+ 0x00000004, /* EMC_QUSE_EXTRA */
+ 0x00000006, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00004282, /* EMC_FBIO_CFG5 */
+ 0x004400a4, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x0007c000, /* EMC_DLL_XFORM_DQS0 */
+ 0x0007c000, /* EMC_DLL_XFORM_DQS1 */
+ 0x0007c000, /* EMC_DLL_XFORM_DQS2 */
+ 0x0007c000, /* EMC_DLL_XFORM_DQS3 */
+ 0x00072000, /* EMC_DLL_XFORM_DQS4 */
+ 0x00072000, /* EMC_DLL_XFORM_DQS5 */
+ 0x00072000, /* EMC_DLL_XFORM_DQS6 */
+ 0x00072000, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x00088000, /* EMC_DLL_XFORM_DQ0 */
+ 0x00088000, /* EMC_DLL_XFORM_DQ1 */
+ 0x00088000, /* EMC_DLL_XFORM_DQ2 */
+ 0x00088000, /* EMC_DLL_XFORM_DQ3 */
+ 0x000e0220, /* EMC_XM2CMDPADCTRL */
+ 0x0800201c, /* EMC_XM2DQSPADCTRL2 */
+ 0x00000000, /* EMC_XM2DQPADCTRL2 */
+ 0x77ffc004, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f008, /* EMC_XM2COMPPADCTRL */
+ 0x00000000, /* EMC_XM2VTTGENPADCTRL */
+ 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x08000068, /* EMC_XM2QUSEPADCTRL */
+ 0x08000000, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00000000, /* EMC_ZCAL_INTERVAL */
+ 0x00000013, /* EMC_ZCAL_WAIT_CNT */
+ 0x00090009, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x80000713, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x00000003, /* MC_EMEM_ARB_CFG */
+ 0xc0000025, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000006, /* MC_EMEM_ARB_TIMING_RC */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x00000005, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000001, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x02030001, /* MC_EMEM_ARB_DA_TURNS */
+ 0x00070506, /* MC_EMEM_ARB_DA_COVERS */
+ 0x71e40a07, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xe0000000, /* EMC_FBIO_SPARE */
+ 0xff00ff00, /* EMC_CFG_RSV */
+ },
+ 0x00000013, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000001, /* EMC_CFG.PERIODIC_QRST */
+ 0x00000000, /* Mode Register 0 */
+ 0x00010042, /* Mode Register 1 */
+ 0x00020001, /* Mode Register 2 */
+ 0x00000001, /* EMC_CFG.DYN_SELF_REF */
+ },
+ {
+ 0x32, /* Rev 3.2 */
+ 533000, /* SDRAM frequency */
+ {
+ 0x0000001f, /* EMC_RC */
+ 0x00000045, /* EMC_RFC */
+ 0x00000016, /* EMC_RAS */
+ 0x00000009, /* EMC_RP */
+ 0x00000008, /* EMC_R2W */
+ 0x00000009, /* EMC_W2R */
+ 0x00000004, /* EMC_R2P */
+ 0x0000000d, /* EMC_W2P */
+ 0x00000009, /* EMC_RD_RCD */
+ 0x00000009, /* EMC_WR_RCD */
+ 0x00000005, /* EMC_RRD */
+ 0x00000003, /* EMC_REXT */
+ 0x00000000, /* EMC_WEXT */
+ 0x00000004, /* EMC_WDV */
+ 0x00000009, /* EMC_QUSE */
+ 0x00000006, /* EMC_QRST */
+ 0x0000000d, /* EMC_QSAFE */
+ 0x00000010, /* EMC_RDV */
+ 0x000007e1, /* EMC_REFRESH */
+ 0x00000000, /* EMC_BURST_REFRESH_NUM */
+ 0x000001f8, /* EMC_PRE_REFRESH_REQ_CNT */
+ 0x00000003, /* EMC_PDEX2WR */
+ 0x00000003, /* EMC_PDEX2RD */
+ 0x00000009, /* EMC_PCHG2PDEN */
+ 0x00000000, /* EMC_ACT2PDEN */
+ 0x00000001, /* EMC_AR2PDEN */
+ 0x0000000f, /* EMC_RW2PDEN */
+ 0x0000004b, /* EMC_TXSR */
+ 0x0000004b, /* EMC_TXSRDLL */
+ 0x00000008, /* EMC_TCKE */
+ 0x0000001b, /* EMC_TFAW */
+ 0x0000000c, /* EMC_TRPAB */
+ 0x00000001, /* EMC_TCLKSTABLE */
+ 0x00000002, /* EMC_TCLKSTOP */
+ 0x000008ab, /* EMC_TREFBW */
+ 0x00000000, /* EMC_QUSE_EXTRA */
+ 0x00000006, /* EMC_FBIO_CFG6 */
+ 0x00000000, /* EMC_ODT_WRITE */
+ 0x00000000, /* EMC_ODT_READ */
+ 0x00006282, /* EMC_FBIO_CFG5 */
+ 0xf0120091, /* EMC_CFG_DIG_DLL */
+ 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
+ 0x00000008, /* EMC_DLL_XFORM_DQS0 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS1 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS2 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS3 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS4 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS5 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS6 */
+ 0x00000008, /* EMC_DLL_XFORM_DQS7 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
+ 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
+ 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
+ 0x0000000c, /* EMC_DLL_XFORM_DQ0 */
+ 0x0000000c, /* EMC_DLL_XFORM_DQ1 */
+ 0x0000000c, /* EMC_DLL_XFORM_DQ2 */
+ 0x0000000c, /* EMC_DLL_XFORM_DQ3 */
+ 0x000a0220, /* EMC_XM2CMDPADCTRL */
+ 0x0800003d, /* EMC_XM2DQSPADCTRL2 */
+ 0x00000000, /* EMC_XM2DQPADCTRL2 */
+ 0x77ffc004, /* EMC_XM2CLKPADCTRL */
+ 0x01f1f408, /* EMC_XM2COMPPADCTRL */
+ 0x00000000, /* EMC_XM2VTTGENPADCTRL */
+ 0x00000007, /* EMC_XM2VTTGENPADCTRL2 */
+ 0x08000068, /* EMC_XM2QUSEPADCTRL */
+ 0x08000000, /* EMC_XM2DQSPADCTRL3 */
+ 0x00000802, /* EMC_CTT_TERM_CTRL */
+ 0x00064000, /* EMC_ZCAL_INTERVAL */
+ 0x000000c0, /* EMC_ZCAL_WAIT_CNT */
+ 0x000e000e, /* EMC_MRS_WAIT_CNT */
+ 0xa0f10202, /* EMC_AUTO_CAL_CONFIG */
+ 0x00000000, /* EMC_CTT */
+ 0x00000000, /* EMC_CTT_DURATION */
+ 0x800010dc, /* EMC_DYN_SELF_REF_CONTROL */
+ 0x00000008, /* MC_EMEM_ARB_CFG */
+ 0x80000060, /* MC_EMEM_ARB_OUTSTANDING_REQ */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_RCD */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_RP */
+ 0x00000010, /* MC_EMEM_ARB_TIMING_RC */
+ 0x0000000a, /* MC_EMEM_ARB_TIMING_RAS */
+ 0x0000000d, /* MC_EMEM_ARB_TIMING_FAW */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_RRD */
+ 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
+ 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
+ 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
+ 0x00000000, /* MC_EMEM_ARB_TIMING_W2W */
+ 0x00000004, /* MC_EMEM_ARB_TIMING_R2W */
+ 0x00000005, /* MC_EMEM_ARB_TIMING_W2R */
+ 0x05040002, /* MC_EMEM_ARB_DA_TURNS */
+ 0x00110c10, /* MC_EMEM_ARB_DA_COVERS */
+ 0x70281811, /* MC_EMEM_ARB_MISC0 */
+ 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
+ 0xe0000000, /* EMC_FBIO_SPARE */
+ 0xff00ff88, /* EMC_CFG_RSV */
+ },
+ 0x00000030, /* EMC_ZCAL_WAIT_CNT after clock change */
+ 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
+ 0x00000001, /* EMC_CFG.PERIODIC_QRST */
+ 0x00000000, /* Mode Register 0 */
+ 0x000100c2, /* Mode Register 1 */
+ 0x00020006, /* Mode Register 2 */
+ 0x00000000, /* EMC_CFG.DYN_SELF_REF */
+ },
+};
+
int enterprise_emc_init(void)
{
struct board_info board_info;
@@ -754,8 +1477,12 @@ int enterprise_emc_init(void)
tegra_get_board_info(&board_info);
if (board_info.fab <= BOARD_FAB_A02)
- tegra_init_emc(enterprise_emc_tables_h5tc2g,
- ARRAY_SIZE(enterprise_emc_tables_h5tc2g));
+ tegra_init_emc(enterprise_emc_tables_kmmll0_a02,
+ ARRAY_SIZE(enterprise_emc_tables_kmmll0_a02));
+ else
+ tegra_init_emc(enterprise_emc_tables_kmkts0_a03,
+ ARRAY_SIZE(enterprise_emc_tables_kmkts0_a03));
+
return 0;
}
diff --git a/arch/arm/mach-tegra/board-enterprise-panel.c b/arch/arm/mach-tegra/board-enterprise-panel.c
index 913a577..5b3dace 100644
--- a/arch/arm/mach-tegra/board-enterprise-panel.c
+++ b/arch/arm/mach-tegra/board-enterprise-panel.c
@@ -28,7 +28,7 @@
#include <linux/tegra_pwm_bl.h>
#include <asm/atomic.h>
#include <linux/nvhost.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dc.h>
@@ -63,6 +63,7 @@
#ifdef CONFIG_TEGRA_DC
static struct regulator *enterprise_dsi_reg;
+static bool dsi_regulator_status;
static struct regulator *enterprise_lcd_reg;
static struct regulator *enterprise_hdmi_reg;
@@ -149,7 +150,6 @@ static bool kernel_1st_panel_init = true;
static int enterprise_backlight_notify(struct device *unused, int brightness)
{
int cur_sd_brightness = atomic_read(&sd_brightness);
- int orig_brightness = brightness;
/* SD brightness is a percentage, 8-bit value. */
brightness = (brightness * cur_sd_brightness) / 255;
@@ -454,27 +454,61 @@ static struct tegra_dc_platform_data enterprise_disp2_pdata = {
.emc_clk_rate = 300000000,
};
-static int enterprise_dsi_panel_enable(void)
+static int avdd_dsi_csi_rail_enable(void)
{
int ret;
- struct board_info board_info;
- tegra_get_board_info(&board_info);
+ if (dsi_regulator_status == true)
+ return 0;
if (enterprise_dsi_reg == NULL) {
enterprise_dsi_reg = regulator_get(NULL, "avdd_dsi_csi");
if (IS_ERR_OR_NULL(enterprise_dsi_reg)) {
pr_err("dsi: Could not get regulator avdd_dsi_csi\n");
- enterprise_dsi_reg = NULL;
- return PTR_ERR(enterprise_dsi_reg);
+ enterprise_dsi_reg = NULL;
+ return PTR_ERR(enterprise_dsi_reg);
}
}
ret = regulator_enable(enterprise_dsi_reg);
if (ret < 0) {
- printk(KERN_ERR
- "DSI regulator avdd_dsi_csi could not be enabled\n");
+ pr_err("DSI regulator avdd_dsi_csi could not be enabled\n");
return ret;
}
+ dsi_regulator_status = true;
+ return 0;
+}
+
+static int avdd_dsi_csi_rail_disable(void)
+{
+ int ret;
+
+ if (dsi_regulator_status == false)
+ return 0;
+
+ if (enterprise_dsi_reg == NULL) {
+ pr_warn("%s: unbalanced disable\n", __func__);
+ return -EIO;
+ }
+
+ ret = regulator_disable(enterprise_dsi_reg);
+ if (ret < 0) {
+ pr_err("DSI regulator avdd_dsi_csi cannot be disabled\n");
+ return ret;
+ }
+ dsi_regulator_status = false;
+ return 0;
+}
+
+static int enterprise_dsi_panel_enable(void)
+{
+ int ret;
+ struct board_info board_info;
+
+ tegra_get_board_info(&board_info);
+
+ ret = avdd_dsi_csi_rail_enable();
+ if (ret)
+ return ret;
#if DSI_PANEL_RESET
@@ -562,8 +596,8 @@ static void enterprise_stereo_set_orientation(int mode)
#ifdef CONFIG_TEGRA_DC
static int enterprise_dsi_panel_postsuspend(void)
{
- /* Do nothing for enterprise dsi panel */
- return 0;
+ /* Disable enterprise dsi rail */
+ return avdd_dsi_csi_rail_disable();
}
#endif
@@ -782,17 +816,12 @@ static void enterprise_panel_early_suspend(struct early_suspend *h)
fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
if (num_registered_fb > 1)
fb_blank(registered_fb[1], FB_BLANK_NORMAL);
-#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
- cpufreq_save_default_governor();
- cpufreq_set_conservative_governor();
- cpufreq_set_conservative_governor_param("up_threshold",
- SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
-
- cpufreq_set_conservative_governor_param("down_threshold",
- SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
- cpufreq_set_conservative_governor_param("freq_step",
- SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
+#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
+ cpufreq_store_default_gov();
+ if (cpufreq_change_gov(cpufreq_conservative_gov))
+ pr_err("Early_suspend: Error changing governor to %s\n",
+ cpufreq_conservative_gov);
#endif
}
@@ -801,7 +830,8 @@ static void enterprise_panel_late_resume(struct early_suspend *h)
unsigned i;
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
- cpufreq_restore_default_governor();
+ if (cpufreq_restore_default_gov())
+ pr_err("Early_suspend: Unable to restore governor\n");
#endif
for (i = 0; i < num_registered_fb; i++)
fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
diff --git a/arch/arm/mach-tegra/board-enterprise-pinmux.c b/arch/arm/mach-tegra/board-enterprise-pinmux.c
index 8d18e32..fc58518 100644
--- a/arch/arm/mach-tegra/board-enterprise-pinmux.c
+++ b/arch/arm/mach-tegra/board-enterprise-pinmux.c
@@ -215,7 +215,7 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux_common[] = {
DEFAULT_PINMUX(LCD_D5, DISPLAYA, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(LCD_D6, RSVD1, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(LCD_D7, RSVD1, NORMAL, NORMAL, OUTPUT),
- DEFAULT_PINMUX(LCD_D8, DISPLAYA, NORMAL, NORMAL, INPUT),
+ DEFAULT_PINMUX(LCD_D8, DISPLAYA, NORMAL, TRISTATE, INPUT),
DEFAULT_PINMUX(LCD_D9, DISPLAYA, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(LCD_D11, DISPLAYA, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(LCD_D12, DISPLAYA, NORMAL, NORMAL, INPUT),
diff --git a/arch/arm/mach-tegra/board-enterprise-power.c b/arch/arm/mach-tegra/board-enterprise-power.c
index 9d7a4d6..c7598ab 100644
--- a/arch/arm/mach-tegra/board-enterprise-power.c
+++ b/arch/arm/mach-tegra/board-enterprise-power.c
@@ -147,6 +147,7 @@ static struct regulator_consumer_supply tps80031_vana_supply_common[] = {
static struct regulator_consumer_supply tps80031_ldo1_supply_a02[] = {
REGULATOR_SUPPLY("avdd_dsi_csi", NULL),
+ REGULATOR_SUPPLY("avdd_hsic", NULL),
REGULATOR_SUPPLY("pwrdet_mipi", NULL),
};
@@ -373,8 +374,8 @@ static struct tps80031_bg_platform_data battery_gauge_data = {
static struct tps80031_subdev_info tps80031_devs_a02[] = {
- TPS80031_DEVS_COMMON,
TPS_REG(VIO, vio, a02),
+ TPS80031_DEVS_COMMON,
TPS_REG(SMPS4, smps4, a02),
TPS_REG(LDO1, ldo1, a02),
TPS_REG(LDO4, ldo4, a02),
@@ -386,8 +387,8 @@ static struct tps80031_subdev_info tps80031_devs_a02[] = {
};
static struct tps80031_subdev_info tps80031_devs_a03[] = {
- TPS80031_DEVS_COMMON,
TPS_REG(VIO, vio, a03),
+ TPS80031_DEVS_COMMON,
TPS_REG(SMPS4, smps4, a03),
TPS_REG(LDO1, ldo1, a03),
TPS_REG(LDO4, ldo4, a03),
@@ -462,7 +463,7 @@ static struct regulator_consumer_supply fixed_reg_vdd_fuse_en_supply[] = {
static struct regulator_consumer_supply gpio_reg_sdmmc3_vdd_sel_supply[] = {
REGULATOR_SUPPLY("vddio_sdmmc3_2v85_1v8", NULL),
REGULATOR_SUPPLY("sdmmc3_compu_pu", NULL),
- REGULATOR_SUPPLY("vddio_sdmmc3", NULL),
+ REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.2"),
REGULATOR_SUPPLY("vsys_3v7", NULL),
};
@@ -643,8 +644,12 @@ FIXED_REG(8, lcd_1v8_en, NULL,
ADD_FIXED_REG(cam_ldo_1v8_en)
static struct platform_device *fixed_regs_devices_a02[] = {
- FIXED_REGS_COMMON,
- ADD_FIXED_REG(pmu_3v3_en),
+ ADD_FIXED_REG(pmu_5v15_en), \
+ ADD_FIXED_REG(pmu_3v3_en), \
+ ADD_FIXED_REG(pmu_hdmi_5v0_en), \
+ ADD_FIXED_REG(vdd_fuse_en), \
+ ADD_FIXED_REG(cam_ldo_2v8_en), \
+ ADD_FIXED_REG(cam_ldo_1v8_en)
};
static struct platform_device *fixed_regs_devices_a03[] = {
diff --git a/arch/arm/mach-tegra/board-enterprise-sdhci.c b/arch/arm/mach-tegra/board-enterprise-sdhci.c
index af1a9ea..4e96908 100644
--- a/arch/arm/mach-tegra/board-enterprise-sdhci.c
+++ b/arch/arm/mach-tegra/board-enterprise-sdhci.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/board-enterprise-sdhci.c
*
- * Copyright (C) 2011 NVIDIA Corporation.
+ * Copyright (C) 2011-2012 NVIDIA Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -109,6 +109,7 @@ static struct resource sdhci_resource3[] = {
},
};
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
static struct embedded_sdio_data embedded_sdio_data0 = {
.cccr = {
.sdio_vsn = 2,
@@ -123,26 +124,36 @@ static struct embedded_sdio_data embedded_sdio_data0 = {
.device = 0x4329,
},
};
+#endif
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
.mmc_data = {
.register_status_notify = enterprise_wifi_status_register,
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
.embedded_sdio = &embedded_sdio_data0,
+#endif
/* FIXME need to revert the built_in change
once we use get the signal strength fix of
bcmdhd driver from broadcom for bcm4329 chipset*/
.built_in = 0,
},
+#ifndef CONFIG_MMC_EMBEDDED_SDIO
+ .pm_flags = MMC_PM_KEEP_POWER,
+#endif
.cd_gpio = -1,
.wp_gpio = -1,
.power_gpio = -1,
+ .tap_delay = 0x0F,
.max_clk_limit = 45000000,
+ .ddr_clk_limit = 41000000,
};
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
.cd_gpio = -1,
.wp_gpio = -1,
.power_gpio = -1,
+ .tap_delay = 0x0F,
+ .ddr_clk_limit = 41000000,
};
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
@@ -150,6 +161,8 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
.wp_gpio = -1,
.power_gpio = -1,
.is_8bit = 1,
+ .tap_delay = 0x0F,
+ .ddr_clk_limit = 41000000,
.mmc_data = {
.built_in = 1,
}
@@ -223,6 +236,20 @@ static int enterprise_wifi_reset(int on)
return 0;
}
+#ifdef CONFIG_TEGRA_PREPOWER_WIFI
+static int __init enterprise_wifi_prepower(void)
+{
+ if (!machine_is_tegra_enterprise())
+ return 0;
+
+ enterprise_wifi_power(1);
+
+ return 0;
+}
+
+subsys_initcall_sync(enterprise_wifi_prepower);
+#endif
+
static int __init enterprise_wifi_init(void)
{
int rc;
diff --git a/arch/arm/mach-tegra/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c
index 71b26469..a95ee61 100644
--- a/arch/arm/mach-tegra/board-enterprise.c
+++ b/arch/arm/mach-tegra/board-enterprise.c
@@ -65,19 +65,17 @@
/* All units are in millicelsius */
static struct tegra_thermal_data thermal_data = {
- .temp_throttle = 85000,
.temp_shutdown = 90000,
.temp_offset = TDIODE_OFFSET, /* temps based on tdiode */
#ifdef CONFIG_TEGRA_EDP_LIMITS
.edp_offset = TDIODE_OFFSET, /* edp based on tdiode */
.hysteresis_edp = 3000,
#endif
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
+ .temp_throttle = 85000,
.tc1 = 0,
.tc2 = 1,
.passive_delay = 2000,
-#else
- .hysteresis_throttle = 1000,
#endif
};
@@ -207,7 +205,7 @@ static struct tegra_i2c_platform_data enterprise_i2c1_platform_data = {
static struct tegra_i2c_platform_data enterprise_i2c2_platform_data = {
.adapter_nr = 1,
.bus_count = 1,
- .bus_clk_rate = { 100000, 0 },
+ .bus_clk_rate = { 400000, 0 },
.is_clkon_always = true,
.scl_gpio = {TEGRA_GPIO_PT5, 0},
.sda_gpio = {TEGRA_GPIO_PT6, 0},
@@ -951,8 +949,17 @@ static void enterprise_baseband_init(void)
static void enterprise_nfc_init(void)
{
+ struct board_info bi;
+
tegra_gpio_enable(TEGRA_GPIO_PS4);
tegra_gpio_enable(TEGRA_GPIO_PM6);
+
+ /* Enable firmware GPIO PX7 for board E1205 */
+ tegra_get_board_info(&bi);
+ if (bi.board_id == BOARD_E1205 && bi.fab >= BOARD_FAB_A03) {
+ nfc_pdata.firm_gpio = TEGRA_GPIO_PX7;
+ tegra_gpio_enable(TEGRA_GPIO_PX7);
+ }
}
static void __init tegra_enterprise_init(void)
diff --git a/arch/arm/mach-tegra/board-harmony-panel.c b/arch/arm/mach-tegra/board-harmony-panel.c
index c240396..9c3d296 100644
--- a/arch/arm/mach-tegra/board-harmony-panel.c
+++ b/arch/arm/mach-tegra/board-harmony-panel.c
@@ -26,7 +26,7 @@
#include <mach/dc.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/tegra_fb.h>
#include <mach/fb.h>
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index 86e9615..9bf8cde 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -425,7 +425,8 @@ static struct tegra_sdhci_platform_data sdhci_pdata4 = {
.is_8bit = 1,
};
-static int __init harmony_wifi_init(void)
+#ifdef CONFIG_TEGRA_PREPOWER_WIFI
+static int __init harmony_wifi_prepower(void)
{
int gpio_pwr, gpio_rst;
@@ -458,7 +459,8 @@ static int __init harmony_wifi_init(void)
* supply of external PMU and 1.2V regulator) are properly enabled,
* and mmc driver has not yet probed for a device on SDIO bus.
*/
-subsys_initcall_sync(harmony_wifi_init);
+subsys_initcall_sync(harmony_wifi_prepower);
+#endif
static void __init tegra_harmony_init(void)
{
diff --git a/arch/arm/mach-tegra/board-kai-memory.c b/arch/arm/mach-tegra/board-kai-memory.c
index 5a22ceb..1f812ec 100644
--- a/arch/arm/mach-tegra/board-kai-memory.c
+++ b/arch/arm/mach-tegra/board-kai-memory.c
@@ -28,126 +28,6 @@
static const struct tegra_emc_table kai_emc_tables_h5tc4g[] = {
{
0x32, /* Rev 3.2 */
- 12750, /* SDRAM frequency */
- {
- 0x00000000, /* EMC_RC */
- 0x00000003, /* EMC_RFC */
- 0x00000000, /* EMC_RAS */
- 0x00000000, /* EMC_RP */
- 0x00000002, /* EMC_R2W */
- 0x0000000a, /* EMC_W2R */
- 0x00000005, /* EMC_R2P */
- 0x0000000b, /* EMC_W2P */
- 0x00000000, /* EMC_RD_RCD */
- 0x00000000, /* EMC_WR_RCD */
- 0x00000003, /* EMC_RRD */
- 0x00000001, /* EMC_REXT */
- 0x00000000, /* EMC_WEXT */
- 0x00000005, /* EMC_WDV */
- 0x00000005, /* EMC_QUSE */
- 0x00000004, /* EMC_QRST */
- 0x00000009, /* EMC_QSAFE */
- 0x0000000b, /* EMC_RDV */
- 0x00000060, /* EMC_REFRESH */
- 0x00000000, /* EMC_BURST_REFRESH_NUM */
- 0x00000018, /* EMC_PRE_REFRESH_REQ_CNT */
- 0x00000002, /* EMC_PDEX2WR */
- 0x00000002, /* EMC_PDEX2RD */
- 0x00000001, /* EMC_PCHG2PDEN */
- 0x00000000, /* EMC_ACT2PDEN */
- 0x00000007, /* EMC_AR2PDEN */
- 0x0000000f, /* EMC_RW2PDEN */
- 0x00000005, /* EMC_TXSR */
- 0x00000005, /* EMC_TXSRDLL */
- 0x00000004, /* EMC_TCKE */
- 0x00000001, /* EMC_TFAW */
- 0x00000000, /* EMC_TRPAB */
- 0x00000004, /* EMC_TCLKSTABLE */
- 0x00000005, /* EMC_TCLKSTOP */
- 0x00000064, /* EMC_TREFBW */
- 0x00000006, /* EMC_QUSE_EXTRA */
- 0x00000004, /* EMC_FBIO_CFG6 */
- 0x00000000, /* EMC_ODT_WRITE */
- 0x00000000, /* EMC_ODT_READ */
- 0x00004288, /* EMC_FBIO_CFG5 */
- 0x007800a4, /* EMC_CFG_DIG_DLL */
- 0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
- 0x000fc000, /* EMC_DLL_XFORM_DQS0 */
- 0x000fc000, /* EMC_DLL_XFORM_DQS1 */
- 0x000fc000, /* EMC_DLL_XFORM_DQS2 */
- 0x000fc000, /* EMC_DLL_XFORM_DQS3 */
- 0x000fc000, /* EMC_DLL_XFORM_DQS4 */
- 0x000fc000, /* EMC_DLL_XFORM_DQS5 */
- 0x000fc000, /* EMC_DLL_XFORM_DQS6 */
- 0x000fc000, /* EMC_DLL_XFORM_DQS7 */
- 0x00000000, /* EMC_DLL_XFORM_QUSE0 */
- 0x00000000, /* EMC_DLL_XFORM_QUSE1 */
- 0x00000000, /* EMC_DLL_XFORM_QUSE2 */
- 0x00000000, /* EMC_DLL_XFORM_QUSE3 */
- 0x00000000, /* EMC_DLL_XFORM_QUSE4 */
- 0x00000000, /* EMC_DLL_XFORM_QUSE5 */
- 0x00000000, /* EMC_DLL_XFORM_QUSE6 */
- 0x00000000, /* EMC_DLL_XFORM_QUSE7 */
- 0x00000000, /* EMC_DLI_TRIM_TXDQS0 */
- 0x00000000, /* EMC_DLI_TRIM_TXDQS1 */
- 0x00000000, /* EMC_DLI_TRIM_TXDQS2 */
- 0x00000000, /* EMC_DLI_TRIM_TXDQS3 */
- 0x00000000, /* EMC_DLI_TRIM_TXDQS4 */
- 0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
- 0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
- 0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
- 0x000fc000, /* EMC_DLL_XFORM_DQ0 */
- 0x000fc000, /* EMC_DLL_XFORM_DQ1 */
- 0x000fc000, /* EMC_DLL_XFORM_DQ2 */
- 0x000fc000, /* EMC_DLL_XFORM_DQ3 */
- 0x000002a0, /* EMC_XM2CMDPADCTRL */
- 0x0800211c, /* EMC_XM2DQSPADCTRL2 */
- 0x00000000, /* EMC_XM2DQPADCTRL2 */
- 0x77fff884, /* EMC_XM2CLKPADCTRL */
- 0x01f1f108, /* EMC_XM2COMPPADCTRL */
- 0x05057404, /* EMC_XM2VTTGENPADCTRL */
- 0x54000007, /* EMC_XM2VTTGENPADCTRL2 */
- 0x08000168, /* EMC_XM2QUSEPADCTRL */
- 0x08000000, /* EMC_XM2DQSPADCTRL3 */
- 0x00000802, /* EMC_CTT_TERM_CTRL */
- 0x00000000, /* EMC_ZCAL_INTERVAL */
- 0x00000040, /* EMC_ZCAL_WAIT_CNT */
- 0x000c000c, /* EMC_MRS_WAIT_CNT */
- 0xa0f10000, /* EMC_AUTO_CAL_CONFIG */
- 0x00000000, /* EMC_CTT */
- 0x00000000, /* EMC_CTT_DURATION */
- 0x800001c5, /* EMC_DYN_SELF_REF_CONTROL */
- 0x00050001, /* MC_EMEM_ARB_CFG */
- 0xc0000008, /* MC_EMEM_ARB_OUTSTANDING_REQ */
- 0x00000001, /* MC_EMEM_ARB_TIMING_RCD */
- 0x00000001, /* MC_EMEM_ARB_TIMING_RP */
- 0x00000002, /* MC_EMEM_ARB_TIMING_RC */
- 0x00000000, /* MC_EMEM_ARB_TIMING_RAS */
- 0x00000001, /* MC_EMEM_ARB_TIMING_FAW */
- 0x00000001, /* MC_EMEM_ARB_TIMING_RRD */
- 0x00000003, /* MC_EMEM_ARB_TIMING_RAP2PRE */
- 0x00000008, /* MC_EMEM_ARB_TIMING_WAP2PRE */
- 0x00000002, /* MC_EMEM_ARB_TIMING_R2R */
- 0x00000001, /* MC_EMEM_ARB_TIMING_W2W */
- 0x00000002, /* MC_EMEM_ARB_TIMING_R2W */
- 0x00000006, /* MC_EMEM_ARB_TIMING_W2R */
- 0x06020102, /* MC_EMEM_ARB_DA_TURNS */
- 0x000a0502, /* MC_EMEM_ARB_DA_COVERS */
- 0x77e30303, /* MC_EMEM_ARB_MISC0 */
- 0x001f0000, /* MC_EMEM_ARB_RING1_THROTTLE */
- 0xe8000000, /* EMC_FBIO_SPARE */
- 0xff00ff00, /* EMC_CFG_RSV */
- },
- 0x00000040, /* EMC_ZCAL_WAIT_CNT after clock change */
- 0x001fffff, /* EMC_AUTO_CAL_INTERVAL */
- 0x00000001, /* EMC_CFG.PERIODIC_QRST */
- 0x80001221, /* Mode Register 0 */
- 0x80100003, /* Mode Register 1 */
- 0x80200008, /* Mode Register 2 */
- 0x00000001, /* EMC_CFG.DYN_SELF_REF */
- },
- {
- 0x32, /* Rev 3.2 */
25500, /* SDRAM frequency */
{
0x00000001, /* EMC_RC */
@@ -526,7 +406,7 @@ static const struct tegra_emc_table kai_emc_tables_h5tc4g[] = {
0x00000005, /* EMC_WDV */
0x00000005, /* EMC_QUSE */
0x00000004, /* EMC_QRST */
- 0x00000009, /* EMC_QSAFE */
+ 0x0000000a, /* EMC_QSAFE */
0x0000000b, /* EMC_RDV */
0x00000607, /* EMC_REFRESH */
0x00000000, /* EMC_BURST_REFRESH_NUM */
@@ -666,20 +546,20 @@ static const struct tegra_emc_table kai_emc_tables_h5tc4g[] = {
0x00000005, /* EMC_TCLKSTOP */
0x00000a2a, /* EMC_TREFBW */
0x00000000, /* EMC_QUSE_EXTRA */
- 0x00000006, /* EMC_FBIO_CFG6 */
+ 0x00000004, /* EMC_FBIO_CFG6 */
0x00000000, /* EMC_ODT_WRITE */
0x00000000, /* EMC_ODT_READ */
0x00007088, /* EMC_FBIO_CFG5 */
0x002600a4, /* EMC_CFG_DIG_DLL */
0x00008000, /* EMC_CFG_DIG_DLL_PERIOD */
- 0x00014000, /* EMC_DLL_XFORM_DQS0 */
- 0x00014000, /* EMC_DLL_XFORM_DQS1 */
- 0x00014000, /* EMC_DLL_XFORM_DQS2 */
- 0x00014000, /* EMC_DLL_XFORM_DQS3 */
- 0x00014000, /* EMC_DLL_XFORM_DQS4 */
- 0x00014000, /* EMC_DLL_XFORM_DQS5 */
- 0x00014000, /* EMC_DLL_XFORM_DQS6 */
- 0x00014000, /* EMC_DLL_XFORM_DQS7 */
+ 0x00034000, /* EMC_DLL_XFORM_DQS0 */
+ 0x00034000, /* EMC_DLL_XFORM_DQS1 */
+ 0x00034000, /* EMC_DLL_XFORM_DQS2 */
+ 0x00034000, /* EMC_DLL_XFORM_DQS3 */
+ 0x00034000, /* EMC_DLL_XFORM_DQS4 */
+ 0x00034000, /* EMC_DLL_XFORM_DQS5 */
+ 0x00034000, /* EMC_DLL_XFORM_DQS6 */
+ 0x00034000, /* EMC_DLL_XFORM_DQS7 */
0x00000000, /* EMC_DLL_XFORM_QUSE0 */
0x00000000, /* EMC_DLL_XFORM_QUSE1 */
0x00000000, /* EMC_DLL_XFORM_QUSE2 */
@@ -696,10 +576,10 @@ static const struct tegra_emc_table kai_emc_tables_h5tc4g[] = {
0x00000000, /* EMC_DLI_TRIM_TXDQS5 */
0x00000000, /* EMC_DLI_TRIM_TXDQS6 */
0x00000000, /* EMC_DLI_TRIM_TXDQS7 */
- 0x00020000, /* EMC_DLL_XFORM_DQ0 */
- 0x00020000, /* EMC_DLL_XFORM_DQ1 */
- 0x00020000, /* EMC_DLL_XFORM_DQ2 */
- 0x00020000, /* EMC_DLL_XFORM_DQ3 */
+ 0x00034000, /* EMC_DLL_XFORM_DQ0 */
+ 0x00034000, /* EMC_DLL_XFORM_DQ1 */
+ 0x00034000, /* EMC_DLL_XFORM_DQ2 */
+ 0x00034000, /* EMC_DLL_XFORM_DQ3 */
0x000002a0, /* EMC_XM2CMDPADCTRL */
0x0800013d, /* EMC_XM2DQSPADCTRL2 */
0x00000000, /* EMC_XM2DQPADCTRL2 */
diff --git a/arch/arm/mach-tegra/board-kai-panel.c b/arch/arm/mach-tegra/board-kai-panel.c
index 53661ce..4073afe 100644
--- a/arch/arm/mach-tegra/board-kai-panel.c
+++ b/arch/arm/mach-tegra/board-kai-panel.c
@@ -27,7 +27,7 @@
#include <linux/pwm_backlight.h>
#include <asm/atomic.h>
#include <linux/nvhost.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dc.h>
@@ -620,27 +620,20 @@ static void kai_panel_early_suspend(struct early_suspend *h)
fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
if (num_registered_fb > 1)
fb_blank(registered_fb[1], FB_BLANK_NORMAL);
-
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
- cpufreq_save_default_governor();
- cpufreq_set_conservative_governor();
- cpufreq_set_conservative_governor_param("up_threshold",
- SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
-
- cpufreq_set_conservative_governor_param("down_threshold",
- SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
-
- cpufreq_set_conservative_governor_param("freq_step",
- SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
+ cpufreq_store_default_gov();
+ if (cpufreq_change_gov(cpufreq_conservative_gov))
+ pr_err("Early_suspend: Error changing governor to %s\n",
+ cpufreq_conservative_gov);
#endif
-
}
static void kai_panel_late_resume(struct early_suspend *h)
{
unsigned i;
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
- cpufreq_restore_default_governor();
+ if (cpufreq_restore_default_gov())
+ pr_err("Early_suspend: Unable to restore governor\n");
#endif
for (i = 0; i < num_registered_fb; i++)
fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
diff --git a/arch/arm/mach-tegra/board-kai-pinmux.c b/arch/arm/mach-tegra/board-kai-pinmux.c
index 1bc64bd..fa750f1 100644
--- a/arch/arm/mach-tegra/board-kai-pinmux.c
+++ b/arch/arm/mach-tegra/board-kai-pinmux.c
@@ -379,7 +379,7 @@ static __initdata struct tegra_pingroup_config kai_pinmux_common[] = {
DEFAULT_PINMUX(SPI2_MISO, SPI2, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(SPI2_MOSI, SPI2, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(KB_ROW11, KBC, NORMAL, NORMAL, OUTPUT),
+ DEFAULT_PINMUX(KB_ROW11, KBC, PULL_UP, TRISTATE, INPUT),
DEFAULT_PINMUX(KB_ROW12, KBC, NORMAL, TRISTATE, OUTPUT),
DEFAULT_PINMUX(KB_ROW13, KBC, NORMAL, TRISTATE, OUTPUT),
};
@@ -469,6 +469,7 @@ static void __init kai_pinmux_audio_init(void)
static struct gpio_init_pin_info init_gpio_mode_kai_common[] = {
GPIO_INIT_PIN_MODE(TEGRA_GPIO_PDD7, false, 0),
GPIO_INIT_PIN_MODE(TEGRA_GPIO_PCC6, false, 0),
+ GPIO_INIT_PIN_MODE(TEGRA_GPIO_PCC7, false, 1),
};
static void __init kai_gpio_init_configure(void)
diff --git a/arch/arm/mach-tegra/board-kai-power.c b/arch/arm/mach-tegra/board-kai-power.c
index edb0ee3..e89b2bd 100644
--- a/arch/arm/mach-tegra/board-kai-power.c
+++ b/arch/arm/mach-tegra/board-kai-power.c
@@ -181,7 +181,7 @@ MAX77663_PDATA_INIT(sd0, 600000, 3387500, NULL, 1, 0, 0,
0, 0, -1, FPS_SRC_NONE, -1, -1, EN2_CTRL_SD0 | SD_FSRADE_DISABLE);
MAX77663_PDATA_INIT(sd1, 800000, 1587500, NULL, 1, 0, 0,
- 1, 1, -1, FPS_SRC_1, -1, -1, SD_FSRADE_DISABLE);
+ 1, 1, -1, FPS_SRC_1, FPS_POWER_PERIOD_0, -1, SD_FSRADE_DISABLE);
MAX77663_PDATA_INIT(sd2, 1800000, 1800000, NULL, 1, 0, 0,
1, 1, -1, FPS_SRC_NONE, -1, -1, 0);
@@ -459,7 +459,7 @@ FIXED_REG(3, en_1v8_cam_a00, en_1v8_cam, max77663_rails(sd2),
FIXED_REG(4, en_vddio_vid_a00, en_vddio_vid, NULL,
0, 0, TEGRA_GPIO_PB2, true, 0, 5000);
FIXED_REG(5, en_3v3_modem_a00, en_3v3_modem, NULL,
- 1, 1, TEGRA_GPIO_PP0, true, 0, 3300);
+ 0, 1, TEGRA_GPIO_PP0, true, 0, 3300);
FIXED_REG(6, en_vdd_pnl_a00, en_vdd_pnl, FIXED_SUPPLY(en_3v3_sys_a00),
0, 0, TEGRA_GPIO_PW1, true, 0, 3300);
FIXED_REG(7, en_cam3_ldo_a00, en_cam3_ldo, FIXED_SUPPLY(en_3v3_sys_a00),
@@ -483,9 +483,9 @@ FIXED_REG(3, en_1v8_cam_a01, en_1v8_cam, max77663_rails(sd2),
FIXED_REG(4, en_vddio_vid_a01, en_vddio_vid, NULL,
0, 0, TEGRA_GPIO_PB2, true, 0, 5000);
FIXED_REG(5, en_3v3_modem_a01, en_3v3_modem, NULL,
- 1, 1, TEGRA_GPIO_PP0, true, 0, 3300);
+ 0, 1, TEGRA_GPIO_PP0, true, 0, 3300);
FIXED_REG(6, en_vdd_pnl_a01, en_vdd_pnl, FIXED_SUPPLY(en_3v3_sys_a01),
- 0, 0, TEGRA_GPIO_PW1, true, 0, 3300);
+ 0, 1, TEGRA_GPIO_PW1, true, 0, 3300);
FIXED_REG(7, en_cam3_ldo_a01, en_cam3_ldo, FIXED_SUPPLY(en_3v3_sys_a01),
0, 0, TEGRA_GPIO_PR7, true, 0, 3300);
FIXED_REG(8, en_vdd_com_a01, en_vdd_com, FIXED_SUPPLY(en_3v3_sys_a01),
diff --git a/arch/arm/mach-tegra/board-kai-sdhci.c b/arch/arm/mach-tegra/board-kai-sdhci.c
index 3e48992..8d1d4a9 100644
--- a/arch/arm/mach-tegra/board-kai-sdhci.c
+++ b/arch/arm/mach-tegra/board-kai-sdhci.c
@@ -101,32 +101,21 @@ static struct resource sdhci_resource3[] = {
},
};
-static struct embedded_sdio_data embedded_sdio_data2 = {
- .cccr = {
- .sdio_vsn = 2,
- .multi_block = 1,
- .low_speed = 0,
- .wide_bus = 0,
- .high_power = 1,
- .high_speed = 1,
- },
- .cis = {
- .vendor = 0x0097,
- .device = 0x4076,
- },
-};
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
.mmc_data = {
.register_status_notify = kai_wifi_status_register,
- /* .embedded_sdio = &embedded_sdio_data2, */
- .built_in = 1,
+ .built_in = 0,
},
+#ifndef CONFIG_MMC_EMBEDDED_SDIO
+ .pm_flags = MMC_PM_KEEP_POWER,
+#endif
.cd_gpio = -1,
.wp_gpio = -1,
.power_gpio = -1,
-/* .tap_delay = 6,
- .is_voltage_switch_supported = false,
+ .tap_delay = 0x0F,
+ .ddr_clk_limit = 41000000,
+/* .is_voltage_switch_supported = false,
.vdd_rail_name = NULL,
.slot_rail_name = NULL,
.vdd_max_uv = -1,
@@ -140,8 +129,9 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
.cd_gpio = KAI_SD_CD,
.wp_gpio = -1,
.power_gpio = -1,
-/* .tap_delay = 6,
- .is_voltage_switch_supported = true,
+ .tap_delay = 0x0F,
+ .ddr_clk_limit = 41000000,
+/* .is_voltage_switch_supported = true,
.vdd_rail_name = "vddio_sdmmc1",
.slot_rail_name = "vddio_sd_slot",
.vdd_max_uv = 3320000,
@@ -156,11 +146,11 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
.power_gpio = -1,
.is_8bit = 1,
.tap_delay = 0x0F,
+ .ddr_clk_limit = 41000000,
.mmc_data = {
.built_in = 1,
}
-/* .tap_delay = 6,
- .is_voltage_switch_supported = false,
+/* .is_voltage_switch_supported = false,
.vdd_rail_name = NULL,
.slot_rail_name = NULL,
.vdd_max_uv = -1,
@@ -227,6 +217,20 @@ static int kai_wifi_power(int power_on)
return 0;
}
+#ifdef CONFIG_TEGRA_PREPOWER_WIFI
+static int __init kai_wifi_prepower(void)
+{
+ if (!machine_is_kai())
+ return 0;
+
+ kai_wifi_power(1);
+
+ return 0;
+}
+
+subsys_initcall_sync(kai_wifi_prepower);
+#endif
+
static int __init kai_wifi_init(void)
{
int rc;
diff --git a/arch/arm/mach-tegra/board-kai-sensors.c b/arch/arm/mach-tegra/board-kai-sensors.c
index 82784ebd..9564aaf 100644
--- a/arch/arm/mach-tegra/board-kai-sensors.c
+++ b/arch/arm/mach-tegra/board-kai-sensors.c
@@ -21,11 +21,14 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/nct1008.h>
#include <linux/cm3217.h>
#include <linux/mpu.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <asm/mach-types.h>
#include <mach/gpio.h>
+#include <mach/thermal.h>
#include <media/ov2710.h>
#include "board.h"
#include "board-kai.h"
@@ -34,6 +37,110 @@
static struct regulator *kai_1v8_cam3;
static struct regulator *kai_vdd_cam3;
+#ifndef CONFIG_TEGRA_INTERNAL_TSENSOR_EDP_SUPPORT
+static int nct_get_temp(void *_data, long *temp)
+{
+ struct nct1008_data *data = _data;
+ return nct1008_thermal_get_temp(data, temp);
+}
+
+static int nct_get_temp_low(void *_data, long *temp)
+{
+ struct nct1008_data *data = _data;
+ return nct1008_thermal_get_temp_low(data, temp);
+}
+
+static int nct_set_limits(void *_data,
+ long lo_limit_milli,
+ long hi_limit_milli)
+{
+ struct nct1008_data *data = _data;
+ return nct1008_thermal_set_limits(data,
+ lo_limit_milli,
+ hi_limit_milli);
+}
+
+static int nct_set_alert(void *_data,
+ void (*alert_func)(void *),
+ void *alert_data)
+{
+ struct nct1008_data *data = _data;
+ return nct1008_thermal_set_alert(data, alert_func, alert_data);
+}
+
+static int nct_set_shutdown_temp(void *_data, long shutdown_temp)
+{
+ struct nct1008_data *data = _data;
+ return nct1008_thermal_set_shutdown_temp(data, shutdown_temp);
+}
+
+static void nct1008_probe_callback(struct nct1008_data *data)
+{
+ struct tegra_thermal_device *thermal_device;
+
+ thermal_device = kzalloc(sizeof(struct tegra_thermal_device),
+ GFP_KERNEL);
+ if (!thermal_device) {
+ pr_err("unable to allocate thermal device\n");
+ return;
+ }
+
+ thermal_device->name = "nct72";
+ thermal_device->data = data;
+ thermal_device->offset = TDIODE_OFFSET;
+ thermal_device->get_temp = nct_get_temp;
+ thermal_device->get_temp_low = nct_get_temp_low;
+ thermal_device->set_limits = nct_set_limits;
+ thermal_device->set_alert = nct_set_alert;
+ thermal_device->set_shutdown_temp = nct_set_shutdown_temp;
+
+ tegra_thermal_set_device(thermal_device);
+}
+#endif
+
+static struct nct1008_platform_data kai_nct1008_pdata = {
+ .supported_hwrev = true,
+ .ext_range = true,
+ .conv_rate = 0x09, /* 0x09 corresponds to 32Hz conversion rate */
+ .offset = 8, /* 4 * 2C. 1C for device accuracies */
+#ifndef CONFIG_TEGRA_INTERNAL_TSENSOR_EDP_SUPPORT
+ .probe_callback = nct1008_probe_callback,
+#endif
+};
+
+static struct i2c_board_info kai_i2c4_nct1008_board_info[] = {
+ {
+ I2C_BOARD_INFO("nct72", 0x4C),
+ .platform_data = &kai_nct1008_pdata,
+ .irq = -1,
+ }
+};
+
+static int kai_nct1008_init(void)
+{
+ int ret = 0;
+
+ /* FIXME: enable irq when throttling is supported */
+ kai_i2c4_nct1008_board_info[0].irq =
+ TEGRA_GPIO_TO_IRQ(KAI_TEMP_ALERT_GPIO);
+
+ ret = gpio_request(KAI_TEMP_ALERT_GPIO, "temp_alert");
+ if (ret < 0) {
+ pr_err("%s: gpio_request failed\n", __func__);
+ return ret;
+ }
+
+ ret = gpio_direction_input(KAI_TEMP_ALERT_GPIO);
+ if (ret < 0) {
+ pr_err("%s: set gpio to input failed\n", __func__);
+ gpio_free(KAI_TEMP_ALERT_GPIO);
+ }
+ else
+ tegra_gpio_enable(KAI_TEMP_ALERT_GPIO);
+
+ return ret;
+}
+
static struct cm3217_platform_data kai_cm3217_pdata = {
.levels = {10, 160, 225, 320, 640, 1280, 2600, 5800, 8000, 10240},
.golden_adc = 0,
@@ -83,7 +190,7 @@ static int kai_ov2710_power_on(void)
kai_vdd_cam3 = regulator_get(NULL, "vdd_cam3");
if (WARN_ON(IS_ERR(kai_vdd_cam3))) {
pr_err("%s: couldn't get regulator vdd_cam3: %d\n",
- __func__, PTR_ERR(kai_vdd_cam3));
+ __func__, (int)PTR_ERR(kai_vdd_cam3));
goto reg_get_vdd_cam3_fail;
}
}
@@ -93,7 +200,7 @@ static int kai_ov2710_power_on(void)
kai_1v8_cam3 = regulator_get(NULL, "vdd_1v8_cam3");
if (WARN_ON(IS_ERR(kai_1v8_cam3))) {
pr_err("%s: couldn't get regulator vdd_1v8_cam3: %d\n",
- __func__, PTR_ERR(kai_1v8_cam3));
+ __func__, (int)PTR_ERR(kai_1v8_cam3));
goto reg_get_vdd_1v8_cam3_fail;
}
}
@@ -245,6 +352,15 @@ static void mpuirq_init(void)
int __init kai_sensors_init(void)
{
+ int err;
+
+ err = kai_nct1008_init();
+ if (err)
+ pr_err("%s: nct1008 init failed\n", __func__);
+ else
+ i2c_register_board_info(4, kai_i2c4_nct1008_board_info,
+ ARRAY_SIZE(kai_i2c4_nct1008_board_info));
+
kai_camera_init();
i2c_register_board_info(2, kai_i2c2_board_info,
diff --git a/arch/arm/mach-tegra/board-kai.c b/arch/arm/mach-tegra/board-kai.c
index fc35f4a..c455fba 100644
--- a/arch/arm/mach-tegra/board-kai.c
+++ b/arch/arm/mach-tegra/board-kai.c
@@ -68,19 +68,17 @@
/* All units are in millicelsius */
static struct tegra_thermal_data thermal_data = {
- .temp_throttle = 85000,
.temp_shutdown = 90000,
.temp_offset = TDIODE_OFFSET, /* temps based on tdiode */
#ifdef CONFIG_TEGRA_EDP_LIMITS
.edp_offset = TDIODE_OFFSET, /* edp based on tdiode */
.hysteresis_edp = 3000,
#endif
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
+ .temp_throttle = 85000,
.tc1 = 0,
.tc2 = 1,
.passive_delay = 2000,
-#else
- .hysteresis_throttle = 1000,
#endif
};
@@ -722,8 +720,6 @@ static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
[0] = {
.instance = 0,
.vbus_gpio = -1,
- .vbus_irq = MAX77663_IRQ_BASE +
- MAX77663_IRQ_ACOK_RISING,
},
[1] = {
.instance = 1,
@@ -815,7 +811,6 @@ static void __init tegra_kai_init(void)
kai_edp_init();
#endif
kai_uart_init();
- kai_tsensor_init();
kai_audio_init();
platform_add_devices(kai_devices, ARRAY_SIZE(kai_devices));
tegra_ram_console_debug_init();
diff --git a/arch/arm/mach-tegra/board-kai.h b/arch/arm/mach-tegra/board-kai.h
index 1f7c16e..d0a1b27 100644
--- a/arch/arm/mach-tegra/board-kai.h
+++ b/arch/arm/mach-tegra/board-kai.h
@@ -95,6 +95,8 @@ int __init touch_init_synaptics_kai(void);
#define KAI_TS_ID1_PG TEGRA_PINGROUP_GMI_WAIT
#define KAI_TS_ID2_PG TEGRA_PINGROUP_GMI_WP_N
+#define KAI_TEMP_ALERT_GPIO TEGRA_GPIO_PS3
+
#define MPU_TYPE_MPU3050 1
#define MPU_TYPE_MPU6050 2
#define MPU_GYRO_TYPE MPU_TYPE_MPU6050
diff --git a/arch/arm/mach-tegra/board-p1852-panel.c b/arch/arm/mach-tegra/board-p1852-panel.c
index 8940af0..ee4c467 100644
--- a/arch/arm/mach-tegra/board-p1852-panel.c
+++ b/arch/arm/mach-tegra/board-p1852-panel.c
@@ -20,7 +20,7 @@
#include <asm/mach-types.h>
#include <linux/platform_device.h>
#include <linux/nvhost.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dc.h>
diff --git a/arch/arm/mach-tegra/board-p1852-pinmux.c b/arch/arm/mach-tegra/board-p1852-pinmux.c
index a59f659..1503c80 100644
--- a/arch/arm/mach-tegra/board-p1852-pinmux.c
+++ b/arch/arm/mach-tegra/board-p1852-pinmux.c
@@ -329,9 +329,9 @@ static __initdata struct tegra_pingroup_config p1852_pinmux_common[] = {
VI_PINMUX(VI_D2, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
VI_PINMUX(VI_D3, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
- VI_PINMUX(VI_D4, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE),
+ VI_PINMUX(VI_D4, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
VI_PINMUX(VI_D5, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
- VI_PINMUX(VI_D6, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE),
+ VI_PINMUX(VI_D6, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
VI_PINMUX(VI_D7, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
VI_PINMUX(VI_D8, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
VI_PINMUX(VI_D9, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
diff --git a/arch/arm/mach-tegra/board-p1852.c b/arch/arm/mach-tegra/board-p1852.c
index 020671a..43bef99 100644
--- a/arch/arm/mach-tegra/board-p1852.c
+++ b/arch/arm/mach-tegra/board-p1852.c
@@ -103,7 +103,7 @@ static __initdata struct tegra_clk_init_table p1852_clk_init_table[] = {
{ "pll_a", NULL, 552960000, false},
{ "pll_a_out0", NULL, 12288000, false},
{ "d_audio", "pll_a_out0", 12288000, false},
- { "nor", "pll_p", 86500000, true},
+ { "nor", "pll_p", 102000000, true},
{ "uarta", "pll_p", 480000000, true},
{ "uartd", "pll_p", 480000000, true},
{ "uarte", "pll_p", 480000000, true},
@@ -141,6 +141,7 @@ static __initdata struct tegra_clk_init_table p1852_clk_init_table[] = {
{ "i2c4", "pll_p", 3200000, true},
{ "i2c5", "pll_p", 3200000, true},
{ "sdmmc2", "pll_p", 104000000, false},
+ {"wake.sclk", NULL, 334000000, true },
{ NULL, NULL, 0, 0},
};
@@ -332,6 +333,11 @@ static void p1852_spi_init(void)
p852_register_spidev();
}
+static struct platform_device tegra_camera = {
+ .name = "tegra_camera",
+ .id = -1,
+};
+
static struct platform_device *p1852_devices[] __initdata = {
#if defined(CONFIG_TEGRA_IOVMM_SMMU)
&tegra_smmu_device,
@@ -339,6 +345,7 @@ static struct platform_device *p1852_devices[] __initdata = {
#if defined(CONFIG_TEGRA_AVP)
&tegra_avp_device,
#endif
+ &tegra_camera,
&tegra_wdt_device
};
@@ -402,12 +409,12 @@ static struct tegra_nor_platform_data p1852_nor_data = {
.chip_parms = {
/* FIXME: Need to use characterized value */
.timing_default = {
- .timing0 = 0xA0400273,
- .timing1 = 0x00030402,
+ .timing0 = 0x30300263,
+ .timing1 = 0x00030302,
},
.timing_read = {
- .timing0 = 0xA0400273,
- .timing1 = 0x00030402,
+ .timing0 = 0x30300263,
+ .timing1 = 0x00030302,
},
},
};
diff --git a/arch/arm/mach-tegra/board-touch-raydium_spi.c b/arch/arm/mach-tegra/board-touch-raydium_spi.c
index 9f5843a..eb13fc4 100644
--- a/arch/arm/mach-tegra/board-touch-raydium_spi.c
+++ b/arch/arm/mach-tegra/board-touch-raydium_spi.c
@@ -220,15 +220,15 @@ int __init touch_init_raydium(int irq_gpio, int reset_gpio, int platform)
switch (platform) {
case 0:
pr_info("Raydium Kai PCB based touch init\n");
- rm31080ts_data.config = rm31080_config_kai_pcb;
+ rm31080ts_data.config = (char *) rm31080_config_kai_pcb;
break;
case 1:
pr_info("Raydium Kai On-Board touch init\n");
- rm31080ts_data.config = rm31080_config_kai_mainboard;
+ rm31080ts_data.config = (char *) rm31080_config_kai_mainboard;
break;
case 2:
pr_info("Raydium cardhu touch init\n");
- rm31080ts_data.config = rm31080_config_cardhu;
+ rm31080ts_data.config = (char *) rm31080_config_cardhu;
break;
default:
pr_err("touch_id error, no touch\n");
diff --git a/arch/arm/mach-tegra/board-touch.h b/arch/arm/mach-tegra/board-touch.h
new file mode 100644
index 00000000..61b64d3
--- /dev/null
+++ b/arch/arm/mach-tegra/board-touch.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-tegra/board-touch.h
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MACH_TEGRA_BOARD_TOUCH_H
+#define _MACH_TEGRA_BOARD_TOUCH_H
+
+
+int __init touch_init_raydium(int irq_gpio, int reset_gpio, int platform);
+
+#endif
diff --git a/arch/arm/mach-tegra/board-ventana-panel.c b/arch/arm/mach-tegra/board-ventana-panel.c
index 4cacd3d..f396557 100644
--- a/arch/arm/mach-tegra/board-ventana-panel.c
+++ b/arch/arm/mach-tegra/board-ventana-panel.c
@@ -27,7 +27,7 @@
#include <linux/earlysuspend.h>
#include <linux/pwm_backlight.h>
#include <linux/nvhost.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dc.h>
@@ -240,8 +240,8 @@ static struct tegra_fb_data ventana_fb_data = {
static struct tegra_fb_data ventana_hdmi_fb_data = {
.win = 0,
- .xres = 1366,
- .yres = 768,
+ .xres = 640,
+ .yres = 480,
.bits_per_pixel = 32,
.flags = TEGRA_FB_FLIP_ON_PROBE,
};
@@ -366,16 +366,10 @@ static void ventana_panel_early_suspend(struct early_suspend *h)
if (num_registered_fb > 1)
fb_blank(registered_fb[1], FB_BLANK_NORMAL);
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
- cpufreq_save_default_governor();
- cpufreq_set_conservative_governor();
- cpufreq_set_conservative_governor_param("up_threshold",
- SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
-
- cpufreq_set_conservative_governor_param("down_threshold",
- SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
-
- cpufreq_set_conservative_governor_param("freq_step",
- SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
+ cpufreq_store_default_gov();
+ if (cpufreq_change_gov(cpufreq_conservative_gov))
+ pr_err("Early_suspend: Error changing governor to %s\n",
+ cpufreq_conservative_gov);
#endif
}
@@ -383,7 +377,8 @@ static void ventana_panel_late_resume(struct early_suspend *h)
{
unsigned i;
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
- cpufreq_restore_default_governor();
+ if (cpufreq_restore_default_gov())
+ pr_err("Early_suspend: Unable to restore governor\n");
#endif
for (i = 0; i < num_registered_fb; i++)
fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
@@ -444,6 +439,11 @@ int __init ventana_panel_init(void)
tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
min(tegra_fb_size, tegra_bootloader_fb_size));
+ /* Copy the bootloader fb to the fb2. */
+ tegra_move_framebuffer(tegra_fb2_start, tegra_bootloader_fb_start,
+ min(tegra_fb2_size, tegra_bootloader_fb_size));
+
+
#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
if (!err)
err = nvhost_device_register(&ventana_disp1_device);
diff --git a/arch/arm/mach-tegra/board-ventana-pinmux.c b/arch/arm/mach-tegra/board-ventana-pinmux.c
index 9f34472..eb37138 100644
--- a/arch/arm/mach-tegra/board-ventana-pinmux.c
+++ b/arch/arm/mach-tegra/board-ventana-pinmux.c
@@ -47,11 +47,11 @@
}
static __initdata struct tegra_drive_pingroup_config ventana_drive_pinmux[] = {
- DEFAULT_DRIVE(DDC),
DEFAULT_DRIVE(VI1),
DEFAULT_DRIVE(SDIO1),
SET_DRIVE(DBG, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
+ SET_DRIVE(DDC, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
SET_DRIVE(VI2, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
SET_DRIVE(AT1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
SET_DRIVE(AO1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST),
@@ -126,7 +126,7 @@ static __initdata struct tegra_pingroup_config ventana_pinmux[] = {
{TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_LPW1, TEGRA_MUX_RSVD, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
- {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
diff --git a/arch/arm/mach-tegra/board-ventana-power.c b/arch/arm/mach-tegra/board-ventana-power.c
index e36a4e7..2acfdfe 100644
--- a/arch/arm/mach-tegra/board-ventana-power.c
+++ b/arch/arm/mach-tegra/board-ventana-power.c
@@ -92,8 +92,8 @@ static struct regulator_consumer_supply tps658621_ldo6_supply[] = {
REGULATOR_SUPPLY("vcsi", "tegra_camera"),
REGULATOR_SUPPLY("vdd_dmic", "tegra-snd-wm8903.0"),
REGULATOR_SUPPLY("vdd_i2c", "3-0030"),
- REGULATOR_SUPPLY("vdd_i2c", "6-0072"),
- REGULATOR_SUPPLY("vdd_i2c", "7-0072"),
+ REGULATOR_SUPPLY("dvdd", "6-0072"),
+ REGULATOR_SUPPLY("dvdd", "7-0072"),
};
static struct regulator_consumer_supply tps658621_ldo7_supply[] = {
REGULATOR_SUPPLY("vdd_ldo7", NULL),
diff --git a/arch/arm/mach-tegra/board-ventana-sdhci.c b/arch/arm/mach-tegra/board-ventana-sdhci.c
index 49720cd..188335a 100644
--- a/arch/arm/mach-tegra/board-ventana-sdhci.c
+++ b/arch/arm/mach-tegra/board-ventana-sdhci.c
@@ -108,6 +108,7 @@ static struct resource sdhci_resource3[] = {
},
};
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
static struct embedded_sdio_data embedded_sdio_data0 = {
.cccr = {
.sdio_vsn = 2,
@@ -122,13 +123,19 @@ static struct embedded_sdio_data embedded_sdio_data0 = {
.device = 0x4329,
},
};
+#endif
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
.mmc_data = {
.register_status_notify = ventana_wifi_status_register,
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
.embedded_sdio = &embedded_sdio_data0,
- .built_in = 1,
+#endif
+ .built_in = 0,
},
+#ifndef CONFIG_MMC_EMBEDDED_SDIO
+ .pm_flags = MMC_PM_KEEP_POWER,
+#endif
.cd_gpio = -1,
.wp_gpio = -1,
.power_gpio = -1,
@@ -224,6 +231,20 @@ static int ventana_wifi_reset(int on)
return 0;
}
+#ifdef CONFIG_TEGRA_PREPOWER_WIFI
+static int __init ventana_wifi_prepower(void)
+{
+ if (!machine_is_ventana())
+ return 0;
+
+ ventana_wifi_power(1);
+
+ return 0;
+}
+
+subsys_initcall_sync(ventana_wifi_prepower);
+#endif
+
static int __init ventana_wifi_init(void)
{
wifi_32k_clk = clk_get_sys(NULL, "blink");
diff --git a/arch/arm/mach-tegra/board-ventana-sensors.c b/arch/arm/mach-tegra/board-ventana-sensors.c
index 81184d5..574bdb2 100644
--- a/arch/arm/mach-tegra/board-ventana-sensors.c
+++ b/arch/arm/mach-tegra/board-ventana-sensors.c
@@ -143,20 +143,32 @@ struct ov2710_platform_data ventana_ov2710_data = {
};
+static struct nvc_gpio_pdata sh532u_left_gpio_pdata[] = {
+ { SH532U_GPIO_RESET, CAM2_RST_L_GPIO, false, 0, },
+ { SH532U_GPIO_GP1, CAM2_LDO_SHUTDN_L_GPIO, false, true, },
+};
+
static struct sh532u_platform_data sh532u_left_pdata = {
+ .cfg = NVC_CFG_NODEV,
.num = 1,
.sync = 2,
.dev_name = "focuser",
- .gpio_reset = CAM2_RST_L_GPIO,
- .gpio_en = CAM2_LDO_SHUTDN_L_GPIO,
+ .gpio_count = ARRAY_SIZE(sh532u_left_gpio_pdata),
+ .gpio = sh532u_left_gpio_pdata,
+};
+
+static struct nvc_gpio_pdata sh532u_right_gpio_pdata[] = {
+ { SH532U_GPIO_RESET, CAM1_RST_L_GPIO, false, 0, },
+ { SH532U_GPIO_GP1, CAM1_LDO_SHUTDN_L_GPIO, false, true, },
};
static struct sh532u_platform_data sh532u_right_pdata = {
+ .cfg = NVC_CFG_NODEV,
.num = 2,
.sync = 1,
.dev_name = "focuser",
- .gpio_reset = CAM1_RST_L_GPIO,
- .gpio_en = CAM1_LDO_SHUTDN_L_GPIO,
+ .gpio_count = ARRAY_SIZE(sh532u_right_gpio_pdata),
+ .gpio = sh532u_right_gpio_pdata,
};
diff --git a/arch/arm/mach-tegra/board-whistler-panel.c b/arch/arm/mach-tegra/board-whistler-panel.c
index 74075d4..d171cf0 100644
--- a/arch/arm/mach-tegra/board-whistler-panel.c
+++ b/arch/arm/mach-tegra/board-whistler-panel.c
@@ -29,7 +29,7 @@
#include <linux/pwm_backlight.h>
#include <linux/tegra_pwm_bl.h>
#include <linux/nvhost.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dc.h>
@@ -318,25 +318,22 @@ static void whistler_panel_early_suspend(struct early_suspend *h)
fb_blank(registered_fb[1], FB_BLANK_NORMAL);
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
- cpufreq_save_default_governor();
- cpufreq_set_conservative_governor();
- cpufreq_set_conservative_governor_param("up_threshold",
- SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
-
- cpufreq_set_conservative_governor_param("down_threshold",
- SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
-
- cpufreq_set_conservative_governor_param("freq_step",
- SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
+ cpufreq_store_default_gov();
+ if (cpufreq_change_gov(cpufreq_conservative_gov))
+ pr_err("Early_suspend: Error changing governor to %s\n",
+ cpufreq_conservative_gov);
#endif
}
static void whistler_panel_late_resume(struct early_suspend *h)
{
unsigned i;
+
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
- cpufreq_restore_default_governor();
+ if (cpufreq_restore_default_gov())
+ pr_err("Early_suspend: Unable to restore governor\n");
#endif
+
for (i = 0; i < num_registered_fb; i++)
fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
}
diff --git a/arch/arm/mach-tegra/board-whistler-pinmux.c b/arch/arm/mach-tegra/board-whistler-pinmux.c
index 22c2f98..15ae9c7 100644
--- a/arch/arm/mach-tegra/board-whistler-pinmux.c
+++ b/arch/arm/mach-tegra/board-whistler-pinmux.c
@@ -64,13 +64,15 @@
}
static __initdata struct tegra_drive_pingroup_config whistler_drive_pinmux[] = {
- DEFAULT_DRIVE(DBG),
- DEFAULT_DRIVE(DDC),
DEFAULT_DRIVE(VI1),
- DEFAULT_DRIVE(VI2),
DEFAULT_DRIVE(SDIO1),
SET_DRIVE(DAP2, DISABLE, ENABLE, DIV_1, 46, 46, SLOWEST, SLOWEST),
SET_DRIVE(DAP3, DISABLE, ENABLE, DIV_1, 46, 46, SLOWEST, SLOWEST),
+ SET_DRIVE(DBG, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST), /* I2C1 */
+ SET_DRIVE(DDC, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST), /* I2C2-1 */
+ SET_DRIVE(AT1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST), /* I2C2-2 */
+ SET_DRIVE(VI2, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST), /* I2C3 */
+ SET_DRIVE(AO1, DISABLE, ENABLE, DIV_1, 31, 31, FASTEST, FASTEST), /* DVC */
};
static __initdata struct tegra_pingroup_config whistler_pinmux[] = {
@@ -93,7 +95,7 @@ static __initdata struct tegra_pingroup_config whistler_pinmux[] = {
{TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
- {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_GMA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_GMC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
@@ -103,7 +105,7 @@ static __initdata struct tegra_pingroup_config whistler_pinmux[] = {
{TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
- {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
@@ -155,7 +157,7 @@ static __initdata struct tegra_pingroup_config whistler_pinmux[] = {
{TEGRA_PINGROUP_OWC, TEGRA_MUX_OWR, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
{TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
- {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
{TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
diff --git a/arch/arm/mach-tegra/board-whistler-sdhci.c b/arch/arm/mach-tegra/board-whistler-sdhci.c
index 08ebe33..d98b1d5 100644
--- a/arch/arm/mach-tegra/board-whistler-sdhci.c
+++ b/arch/arm/mach-tegra/board-whistler-sdhci.c
@@ -144,6 +144,7 @@ static struct resource sdhci_resource3[] = {
},
};
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
static struct embedded_sdio_data embedded_sdio_data1 = {
.cccr = {
.sdio_vsn = 2,
@@ -158,13 +159,19 @@ static struct embedded_sdio_data embedded_sdio_data1 = {
.device = 0x4329,
},
};
+#endif
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data1 = {
.mmc_data = {
.register_status_notify = whistler_wifi_status_register,
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
.embedded_sdio = &embedded_sdio_data1,
- .built_in = 1,
+#endif
+ .built_in = 0,
},
+#ifndef CONFIG_MMC_EMBEDDED_SDIO
+ .pm_flags = MMC_PM_KEEP_POWER,
+#endif
.cd_gpio = -1,
.wp_gpio = -1,
.power_gpio = -1,
@@ -216,6 +223,20 @@ static struct platform_device tegra_sdhci_device3 = {
},
};
+#ifdef CONFIG_TEGRA_PREPOWER_WIFI
+static int __init whistler_wifi_prepower(void)
+{
+ if (!machine_is_whistler())
+ return 0;
+
+ whistler_wifi_power(1);
+
+ return 0;
+}
+
+subsys_initcall_sync(whistler_wifi_prepower);
+#endif
+
static int __init whistler_wifi_init(void)
{
gpio_request(WHISTLER_WLAN_PWR, "wlan_power");
diff --git a/arch/arm/mach-tegra/board-whistler.c b/arch/arm/mach-tegra/board-whistler.c
index f124645..ede0d0b 100644
--- a/arch/arm/mach-tegra/board-whistler.c
+++ b/arch/arm/mach-tegra/board-whistler.c
@@ -266,6 +266,7 @@ static struct tegra_i2c_platform_data whistler_i2c1_platform_data = {
.scl_gpio = {TEGRA_GPIO_PC4, 0},
.sda_gpio = {TEGRA_GPIO_PC5, 0},
.arb_recovery = arb_lost_recovery,
+ .slave_addr = 0xFC,
};
static const struct tegra_pingroup_config i2c2_ddc = {
@@ -287,6 +288,7 @@ static struct tegra_i2c_platform_data whistler_i2c2_platform_data = {
.scl_gpio = {0, TEGRA_GPIO_PT5},
.sda_gpio = {0, TEGRA_GPIO_PT6},
.arb_recovery = arb_lost_recovery,
+ .slave_addr = 0xFC,
};
static struct tegra_i2c_platform_data whistler_i2c3_platform_data = {
@@ -296,6 +298,7 @@ static struct tegra_i2c_platform_data whistler_i2c3_platform_data = {
.scl_gpio = {TEGRA_GPIO_PBB2, 0},
.sda_gpio = {TEGRA_GPIO_PBB3, 0},
.arb_recovery = arb_lost_recovery,
+ .slave_addr = 0xFC,
};
static struct tegra_i2c_platform_data whistler_dvc_platform_data = {
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 6d5a93c..63095ce 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -24,6 +24,7 @@
#include <linux/types.h>
#include <linux/power_supply.h>
+#include <linux/memory.h>
#define ADD_FIXED_VOLTAGE_REG(_name) (&_name##_fixed_voltage_device)
@@ -67,6 +68,14 @@
}
#endif
+/* This information is passed by bootloader */
+#define COMMCHIP_UNKNOWN 0
+#define COMMCHIP_NOCHIP 1
+#define COMMCHIP_BROADCOM_BCM4329 2
+#define COMMCHIP BROADCOM_BCM4330 3
+#define COMMCHIP_MARVELL_SD8797 4
+
+
struct memory_accessor;
void tegra_assert_system_reset(char mode, const char *cmd);
@@ -148,19 +157,21 @@ void tegra_get_board_info(struct board_info *);
void tegra_get_pmu_board_info(struct board_info *bi);
void tegra_get_display_board_info(struct board_info *bi);
void tegra_get_camera_board_info(struct board_info *bi);
+
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
-#define SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD 95
-#define SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD 50
-#define SET_CONSERVATIVE_GOVERNOR_FREQ_STEP 3
-
-void cpufreq_save_default_governor(void);
-void cpufreq_restore_default_governor(void);
-void cpufreq_set_conservative_governor(void);
-void cpufreq_set_conservative_governor_param(char *name, int value);
+#define MAX_GOV_NAME_LEN 16
+extern char cpufreq_default_gov[][MAX_GOV_NAME_LEN];
+extern char *cpufreq_conservative_gov;
+
+void cpufreq_store_default_gov(void);
+int cpufreq_restore_default_gov(void);
+int cpufreq_change_gov(char *target_gov);
#endif
+
int get_core_edp(void);
enum panel_type get_panel_type(void);
int tegra_get_modem_id(void);
+int tegra_get_commchip_id(void);
enum power_supply_type get_power_supply_type(void);
enum audio_codec_type get_audio_codec_type(void);
int get_maximum_cpu_current_supported(void);
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index f31da0b..66a954f 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -238,16 +238,9 @@ void clk_init(struct clk *c)
static int clk_enable_locked(struct clk *c)
{
int ret = 0;
- int rate = clk_get_rate_locked(c);
- bool set_rate = false;
-
- if (rate > c->max_rate) {
- rate = c->max_rate;
- set_rate = true;
- }
if (clk_is_auto_dvfs(c)) {
- ret = tegra_dvfs_set_rate(c, rate);
+ ret = tegra_dvfs_set_rate(c, clk_get_rate_locked(c));
if (ret)
return ret;
}
@@ -259,9 +252,6 @@ static int clk_enable_locked(struct clk *c)
return ret;
}
- if (set_rate)
- clk_set_rate_locked(c, rate);
-
if (c->ops && c->ops->enable) {
ret = c->ops->enable(c);
trace_clock_enable(c->name, 1, 0);
@@ -525,13 +515,11 @@ unsigned long clk_get_rate_all_locked(struct clk *c)
return rate;
}
-long clk_round_rate(struct clk *c, unsigned long rate)
+long clk_round_rate_locked(struct clk *c, unsigned long rate)
{
- unsigned long flags, max_rate;
+ unsigned long max_rate;
long ret;
- clk_lock_save(c, &flags);
-
if (!c->ops || !c->ops->round_rate) {
ret = -ENOSYS;
goto out;
@@ -544,6 +532,16 @@ long clk_round_rate(struct clk *c, unsigned long rate)
ret = c->ops->round_rate(c, rate);
out:
+ return ret;
+}
+
+long clk_round_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long flags;
+ long ret;
+
+ clk_lock_save(c, &flags);
+ ret = clk_round_rate_locked(c, rate);
clk_unlock_restore(c, &flags);
return ret;
}
@@ -1299,6 +1297,10 @@ static int clk_debugfs_register_one(struct clk *c)
if (!d)
goto err_out;
+ d = debugfs_create_u32("min", S_IRUGO, c->dent, (u32 *)&c->min_rate);
+ if (!d)
+ goto err_out;
+
d = debugfs_create_file(
"parent", parent_rate_mode, c->dent, c, &parent_fops);
if (!d)
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index dde9e07..a9945e3 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -240,6 +240,7 @@ unsigned long clk_get_min_rate(struct clk *c);
unsigned long clk_get_rate_locked(struct clk *c);
int clk_set_rate_locked(struct clk *c, unsigned long rate);
int clk_set_parent_locked(struct clk *c, struct clk *parent);
+long clk_round_rate_locked(struct clk *c, unsigned long rate);
int tegra_clk_shared_bus_update(struct clk *c);
void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
void tegra3_set_cpu_skipper_delay(int delay);
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 4786ace..78bd77d 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -28,6 +28,7 @@
#include <linux/memblock.h>
#include <linux/bitops.h>
#include <linux/sched.h>
+#include <linux/cpufreq.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/system.h>
@@ -141,6 +142,7 @@ void tegra_assert_system_reset(char mode, const char *cmd)
#endif
}
static int modem_id;
+static int commchip_id;
static int sku_override;
static int debug_uart_port_id;
static enum audio_codec_type audio_codec_name;
@@ -153,6 +155,11 @@ static int max_cpu_current;
static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
/* name parent rate enabled */
{ "clk_m", NULL, 0, true },
+ { "emc", NULL, 0, true },
+ { "cpu", NULL, 0, true },
+ { "kfuse", NULL, 0, true },
+ { "fuse", NULL, 0, true },
+ { "sclk", NULL, 0, true },
#ifdef CONFIG_TEGRA_SILICON_PLATFORM
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
{ "pll_p", NULL, 216000000, true },
@@ -181,14 +188,7 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
{ "sclk", "pll_p_out4", 102000000, true },
{ "hclk", "sclk", 102000000, true },
{ "pclk", "hclk", 51000000, true },
- { "wake.sclk", NULL, 40000000, true },
- { "sbc5.sclk", NULL, 40000000, false},
- { "sbc6.sclk", NULL, 40000000, false},
#endif
- { "sbc1.sclk", NULL, 40000000, false},
- { "sbc2.sclk", NULL, 40000000, false},
- { "sbc3.sclk", NULL, 40000000, false},
- { "sbc4.sclk", NULL, 40000000, false},
#else
{ "pll_p", NULL, 216000000, true },
{ "pll_p_out1", "pll_p", 28800000, false },
@@ -199,25 +199,24 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
{ "sclk", "pll_p_out4", 108000000, true },
{ "hclk", "sclk", 108000000, true },
{ "pclk", "hclk", 54000000, true },
- { "pll_c", NULL, ULONG_MAX, false },
- { "pll_c_out1", "pll_c", 208000000, false },
#endif
#ifdef CONFIG_TEGRA_SLOW_CSITE
{ "csite", "clk_m", 1000000, true },
#else
{ "csite", NULL, 0, true },
#endif
- { "emc", NULL, 0, true },
- { "cpu", NULL, 0, true },
- { "kfuse", NULL, 0, true },
- { "fuse", NULL, 0, true },
{ "pll_u", NULL, 480000000, false },
{ "sdmmc1", "pll_p", 48000000, false},
{ "sdmmc3", "pll_p", 48000000, false},
{ "sdmmc4", "pll_p", 48000000, false},
- { "pll_a", "pll_p_out1", 0, false},
- { "pll_a_out0", "pll_a", 0, false},
+ { "sbc1.sclk", NULL, 40000000, false},
+ { "sbc2.sclk", NULL, 40000000, false},
+ { "sbc3.sclk", NULL, 40000000, false},
+ { "sbc4.sclk", NULL, 40000000, false},
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ { "sbc5.sclk", NULL, 40000000, false},
+ { "sbc6.sclk", NULL, 40000000, false},
+ { "wake.sclk", NULL, 40000000, true },
{ "cbus", "pll_c", 416000000, false },
{ "pll_c_out1", "pll_c", 208000000, false },
{ "mselect", "pll_p", 102000000, true },
@@ -301,8 +300,6 @@ void tegra_init_cache(bool init)
{
void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
u32 aux_ctrl;
- u32 speedo;
- u32 tmp;
#ifdef CONFIG_TRUSTED_FOUNDATIONS
/* issue the SMC to enable the L2 */
@@ -329,6 +326,8 @@ void tegra_init_cache(bool init)
writel(0x221, p + L2X0_TAG_LATENCY_CTRL);
writel(0x221, p + L2X0_DATA_LATENCY_CTRL);
} else {
+ u32 speedo;
+
/* relax l2-cache latency for speedos 4,5,6 (T33's chips) */
speedo = tegra_cpu_speedo_id();
if (speedo == 4 || speedo == 5 || speedo == 6 ||
@@ -345,12 +344,15 @@ void tegra_init_cache(bool init)
writel(0x770, p + L2X0_DATA_LATENCY_CTRL);
#endif
#endif
+ writel(0x3, p + L2X0_POWER_CTRL);
aux_ctrl = readl(p + L2X0_CACHE_TYPE);
aux_ctrl = (aux_ctrl & 0x700) << (17-8);
aux_ctrl |= 0x7C000001;
if (init) {
l2x0_init(p, aux_ctrl, 0x8200c3fe);
} else {
+ u32 tmp;
+
tmp = aux_ctrl;
aux_ctrl = readl(p + L2X0_AUX_CTRL);
aux_ctrl &= 0x8200c3fe;
@@ -711,6 +713,22 @@ int tegra_get_modem_id(void)
__setup("modem_id=", tegra_modem_id);
+static int __init tegra_commchip_id(char *id)
+{
+ char *p = id;
+
+ if (get_option(&p, &commchip_id) != 1)
+ return 0;
+ return 1;
+}
+
+int tegra_get_commchip_id(void)
+{
+ return commchip_id;
+}
+
+__setup("commchip_id=", tegra_commchip_id);
+
/*
* Tegra has a protected aperture that prevents access by most non-CPU
* memory masters to addresses above the aperture value. Enabling it
@@ -778,28 +796,9 @@ out:
iounmap(to_io);
}
-#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000
-#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 1
-#else
-#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 0
-#endif
-#if FORCE_SMMU_BASE_FOR_TEGRA3_A01 || \
- (defined(CONFIG_TEGRA_IOVMM_SMMU) && defined(CONFIG_ARCH_TEGRA_3x_SOC))
-/* Support for Tegra3 A01 chip mask that needs to have SMMU IOVA reside in
- * the upper half of 4GB IOVA space. A02 and after use the bottom 1GB and
- * do not need to reserve memory.
- */
-#define SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
-#endif
-
void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
unsigned long fb2_size)
{
-#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
- int smmu_reserved = 0;
- struct tegra_smmu_window *smmu_window = tegra_smmu_window(0);
-#endif
-
if (carveout_size) {
tegra_carveout_start = memblock_end_of_DRAM() - carveout_size;
if (memblock_remove(tegra_carveout_start, carveout_size)) {
@@ -845,33 +844,6 @@ void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture)
tegra_grhost_aperture = tegra_carveout_start;
-#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
- if (!smmu_window) {
- pr_err("No SMMU resource\n");
- } else {
- size_t smmu_window_size;
-
- if (FORCE_SMMU_BASE_FOR_TEGRA3_A01 ||
- (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3 &&
- tegra_get_revision() == TEGRA_REVISION_A01)) {
- smmu_window->start = TEGRA_SMMU_BASE_TEGRA3_A01;
- smmu_window->end = TEGRA_SMMU_BASE_TEGRA3_A01 +
- TEGRA_SMMU_SIZE_TEGRA3_A01 - 1;
- }
- smmu_window_size = smmu_window->end + 1 - smmu_window->start;
- if (smmu_window->start >= 0x80000000) {
- if (memblock_reserve(smmu_window->start,
- smmu_window_size))
- pr_err(
- "Failed to reserve SMMU I/O VA window %08lx@%08lx\n",
- (unsigned long)smmu_window_size,
- (unsigned long)smmu_window->start);
- else
- smmu_reserved = 1;
- }
- }
-#endif
-
if (tegra_lp0_vec_size &&
(tegra_lp0_vec_start < memblock_end_of_DRAM())) {
if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
@@ -925,12 +897,6 @@ void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
tegra_vpr_start,
tegra_vpr_size ?
tegra_vpr_start + tegra_vpr_size - 1 : 0);
-
-#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
- if (smmu_reserved)
- pr_info("SMMU: %08lx - %08lx\n",
- smmu_window->start, smmu_window->end);
-#endif
}
static struct resource ram_console_resources[] = {
@@ -988,118 +954,53 @@ void __init tegra_release_bootloader_fb(void)
}
#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
-static char cpufreq_gov_default[32];
-static char *cpufreq_gov_conservative = "conservative";
-static char *cpufreq_sysfs_place_holder="/sys/devices/system/cpu/cpu%i/cpufreq/scaling_governor";
-static char *cpufreq_gov_conservative_param="/sys/devices/system/cpu/cpufreq/conservative/%s";
+char cpufreq_default_gov[CONFIG_NR_CPUS][MAX_GOV_NAME_LEN];
+char *cpufreq_conservative_gov = "conservative";
-static void cpufreq_set_governor(char *governor)
+void cpufreq_store_default_gov(void)
{
- struct file *scaling_gov = NULL;
- mm_segment_t old_fs;
- char buf[128];
- int i = 0;
- loff_t offset = 0;
-
- if (governor == NULL)
- return;
+ unsigned int cpu;
+ struct cpufreq_policy *policy;
- /* change to KERNEL_DS address limit */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
- for_each_online_cpu(i)
-#endif
- {
- sprintf(buf, cpufreq_sysfs_place_holder, i);
- scaling_gov = filp_open(buf, O_RDWR, 0);
- if (scaling_gov != NULL) {
- if (scaling_gov->f_op != NULL &&
- scaling_gov->f_op->write != NULL)
- scaling_gov->f_op->write(scaling_gov,
- governor,
- strlen(governor),
- &offset);
- else
- pr_err("f_op might be null\n");
-
- filp_close(scaling_gov, NULL);
- } else {
- pr_err("%s. Can't open %s\n", __func__, buf);
+ for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) {
+ policy = cpufreq_cpu_get(cpu);
+ if (policy) {
+ sprintf(cpufreq_default_gov[cpu], "%s",
+ policy->governor->name);
+ cpufreq_cpu_put(policy);
}
}
- set_fs(old_fs);
}
-void cpufreq_save_default_governor(void)
+int cpufreq_change_gov(char *target_gov)
{
- struct file *scaling_gov = NULL;
- mm_segment_t old_fs;
- char buf[128];
- loff_t offset = 0;
-
- /* change to KERNEL_DS address limit */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- buf[127] = 0;
- sprintf(buf, cpufreq_sysfs_place_holder,0);
- scaling_gov = filp_open(buf, O_RDONLY, 0);
- if (scaling_gov != NULL) {
- if (scaling_gov->f_op != NULL &&
- scaling_gov->f_op->read != NULL)
- scaling_gov->f_op->read(scaling_gov,
- cpufreq_gov_default,
- 32,
- &offset);
- else
- pr_err("f_op might be null\n");
+ unsigned int cpu = 0;
- filp_close(scaling_gov, NULL);
- } else {
- pr_err("%s. Can't open %s\n", __func__, buf);
- }
- set_fs(old_fs);
-}
-
-void cpufreq_restore_default_governor(void)
-{
- cpufreq_set_governor(cpufreq_gov_default);
+#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
+ for_each_online_cpu(cpu)
+#endif
+ return cpufreq_set_gov(target_gov, cpu);
}
-void cpufreq_set_conservative_governor_param(char *name, int value)
+int cpufreq_restore_default_gov(void)
{
- struct file *gov_param = NULL;
- mm_segment_t old_fs;
- static char buf[128], param_value[8];
- loff_t offset = 0;
-
- /* change to KERNEL_DS address limit */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- sprintf(param_value, "%d", value);
- sprintf(buf, cpufreq_gov_conservative_param, name);
- gov_param = filp_open(buf, O_RDWR, 0);
- if (gov_param != NULL) {
- if (gov_param->f_op != NULL &&
- gov_param->f_op->write != NULL)
- gov_param->f_op->write(gov_param,
- param_value,
- strlen(param_value),
- &offset);
- else
- pr_err("f_op might be null\n");
+ int ret = 0;
+ unsigned int cpu;
- filp_close(gov_param, NULL);
- } else {
- pr_err("%s. Can't open %s\n", __func__, buf);
+ for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) {
+ if (strlen((const char *)&cpufreq_default_gov[cpu])) {
+ ret = cpufreq_set_gov(cpufreq_default_gov[cpu], cpu);
+ if (ret < 0)
+ /* Unable to restore gov for the cpu as
+ * It was online on suspend and becomes
+ * offline on resume.
+ */
+ pr_info("Unable to restore gov:%s for cpu:%d,"
+ , cpufreq_default_gov[cpu]
+ , cpu);
+ }
+ cpufreq_default_gov[cpu][0] = '\0';
}
- set_fs(old_fs);
-}
-
-void cpufreq_set_conservative_governor(void)
-{
- cpufreq_set_governor(cpufreq_gov_conservative);
+ return ret;
}
#endif /* CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND */
diff --git a/arch/arm/mach-tegra/cpu-tegra3.c b/arch/arm/mach-tegra/cpu-tegra3.c
index d17e79c..86a0b13 100644
--- a/arch/arm/mach-tegra/cpu-tegra3.c
+++ b/arch/arm/mach-tegra/cpu-tegra3.c
@@ -147,9 +147,12 @@ static int hp_state_set(const char *arg, const struct kernel_param *kp)
if (ret == 0) {
if ((hp_state == TEGRA_HP_DISABLED) &&
- (old_state != TEGRA_HP_DISABLED))
+ (old_state != TEGRA_HP_DISABLED)) {
+ mutex_unlock(tegra3_cpu_lock);
+ cancel_delayed_work_sync(&hotplug_work);
+ mutex_lock(tegra3_cpu_lock);
pr_info("Tegra auto-hotplug disabled\n");
- else if (hp_state != TEGRA_HP_DISABLED) {
+ } else if (hp_state != TEGRA_HP_DISABLED) {
if (old_state == TEGRA_HP_DISABLED) {
pr_info("Tegra auto-hotplug enabled\n");
hp_init_stats();
@@ -324,7 +327,10 @@ void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend)
if (!is_g_cluster_present())
return;
- if (suspend && (hp_state != TEGRA_HP_DISABLED)) {
+ if (hp_state == TEGRA_HP_DISABLED)
+ return;
+
+ if (suspend) {
hp_state = TEGRA_HP_IDLE;
/* Switch to G-mode if suspend rate is high enough */
@@ -357,8 +363,6 @@ void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend)
}
switch (hp_state) {
- case TEGRA_HP_DISABLED:
- break;
case TEGRA_HP_IDLE:
if (cpu_freq > top_freq) {
hp_state = TEGRA_HP_UP;
diff --git a/arch/arm/mach-tegra/cpuidle-t2.c b/arch/arm/mach-tegra/cpuidle-t2.c
index d7b787bc..ff6c320 100644
--- a/arch/arm/mach-tegra/cpuidle-t2.c
+++ b/arch/arm/mach-tegra/cpuidle-t2.c
@@ -40,7 +40,6 @@
#include <linux/tick.h>
#include <asm/cpu_pm.h>
-#include <asm/suspend.h>
#include <mach/iomap.h>
#include <mach/irqs.h>
@@ -50,6 +49,7 @@
#include "pm.h"
#include "sleep.h"
#include "timer.h"
+#include "dvfs.h"
static struct {
unsigned int cpu_ready_count[2];
@@ -222,6 +222,7 @@ static int tegra2_idle_lp2_cpu_0(struct cpuidle_device *dev,
idle_stats.tear_down_count++;
entry_time = ktime_get();
+ tegra_dvfs_rail_off(tegra_cpu_rail, entry_time);
if (request > state->target_residency) {
s64 sleep_time = request - tegra_lp2_exit_latency;
@@ -248,6 +249,8 @@ static int tegra2_idle_lp2_cpu_0(struct cpuidle_device *dev,
}
exit_time = ktime_get();
+ tegra_dvfs_rail_on(tegra_cpu_rail, exit_time);
+
if (sleep_completed) {
/*
* Stayed in LP2 for the full time until the next tick,
diff --git a/arch/arm/mach-tegra/cpuidle-t3.c b/arch/arm/mach-tegra/cpuidle-t3.c
index 9a19a8a..c6a50a5 100644
--- a/arch/arm/mach-tegra/cpuidle-t3.c
+++ b/arch/arm/mach-tegra/cpuidle-t3.c
@@ -43,7 +43,6 @@
#include <asm/cpu_pm.h>
#include <asm/hardware/gic.h>
#include <asm/localtimer.h>
-#include <asm/suspend.h>
#include <mach/iomap.h>
#include <mach/irqs.h>
@@ -378,7 +377,7 @@ static void tegra3_idle_enter_lp2_cpu_n(struct cpuidle_device *dev,
tegra_cpu_wake_by_time[dev->cpu] = ktime_to_us(entry_time) + request;
smp_wmb();
- cpu_suspend(0, tegra3_sleep_cpu_secondary_finish);
+ tegra3_sleep_cpu_secondary(PLAT_PHYS_OFFSET - PAGE_OFFSET);
tegra_cpu_wake_by_time[dev->cpu] = LLONG_MAX;
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index 202c767..2a4f94c 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -1232,8 +1232,8 @@ static struct fsl_usb2_platform_data tegra_udc_pdata = {
};
struct platform_device tegra_udc_device = {
- .name = "fsl-tegra-udc",
- .id = -1,
+ .name = "tegra-udc",
+ .id = 0,
.dev = {
.dma_mask = &tegra_udc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index 66f9c24..e4fe67f 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -394,7 +394,8 @@ skip_status:
spin_unlock_irqrestore(&ch->lock, irq_flags);
/* Callback should be called without any lock */
- req->complete(req);
+ if(req->complete)
+ req->complete(req);
return 0;
}
EXPORT_SYMBOL(tegra_dma_dequeue_req);
@@ -678,6 +679,12 @@ void tegra_dma_free_channel(struct tegra_dma_channel *ch)
}
EXPORT_SYMBOL(tegra_dma_free_channel);
+int tegra_dma_get_channel_id(struct tegra_dma_channel *ch)
+{
+ return ch->id;
+}
+EXPORT_SYMBOL(tegra_dma_get_channel_id);
+
static bool tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
struct tegra_dma_req *req)
{
@@ -751,7 +758,10 @@ static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
u32 apb_ptr;
u32 csr;
- csr = CSR_IE_EOC | CSR_FLOW;
+ csr = CSR_FLOW;
+ if (req->complete || req->threshold)
+ csr |= CSR_IE_EOC;
+
ahb_seq = AHB_SEQ_INTR_ENB;
switch (req->req_sel) {
diff --git a/arch/arm/mach-tegra/dvfs.h b/arch/arm/mach-tegra/dvfs.h
index eaecf42..a53a04b 100644
--- a/arch/arm/mach-tegra/dvfs.h
+++ b/arch/arm/mach-tegra/dvfs.h
@@ -21,7 +21,7 @@
#ifndef _TEGRA_DVFS_H_
#define _TEGRA_DVFS_H_
-#define MAX_DVFS_FREQS 18
+#define MAX_DVFS_FREQS 20
#define DVFS_RAIL_STATS_TOP_BIN 40
struct clk;
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index d9fe1b0..6df9da9 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -2,7 +2,7 @@
* arch/arm/mach-tegra/fuse.c
*
* Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2010-2011 NVIDIA Corp.
+ * Copyright (C) 2010-2012 NVIDIA Corp.
*
* Author:
* Colin Cross <ccross@android.com>
@@ -70,8 +70,6 @@ struct tegra_id {
};
static struct tegra_id tegra_id;
-static unsigned int tegra_chip_id;
-static unsigned int tegra_chip_rev;
static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
[TEGRA_REVISION_UNKNOWN] = "unknown",
@@ -343,19 +341,6 @@ static enum tegra_revision tegra_decode_revision(const struct tegra_id *id)
revision = tegra_chip_revisions[i].revision;
break;
}
-
-#elif defined(CONFIG_TEGRA_FPGA_PLATFORM)
- if ((id->chipid & 0xf0) == TEGRA_CHIPID_TEGRA3) {
- if ((id->major == 0) && (id->minor == 1)) {
- unsigned int patch = id->patch & 0xF;
- if ((id->netlist == 12) && (patch == 12))
- revision = TEGRA_REVISION_A01;
- else if ((id->netlist == 12) && (patch > 12))
- revision = TEGRA_REVISION_A02;
- else if (id->netlist > 12)
- revision = TEGRA_REVISION_A02;
- }
- }
#endif
return revision;
@@ -396,66 +381,37 @@ static void tegra_get_tegraid_from_hw(void)
enum tegra_chipid tegra_get_chipid(void)
{
- if (tegra_id.chipid == TEGRA_CHIPID_UNKNOWN) {
- /* Boot loader did not pass a valid chip ID.
- * Get it from hardware */
+ if (tegra_id.chipid == TEGRA_CHIPID_UNKNOWN)
tegra_get_tegraid_from_hw();
- }
return tegra_id.chipid;
}
enum tegra_revision tegra_get_revision(void)
{
- if (tegra_id.chipid == TEGRA_CHIPID_UNKNOWN) {
- /* Boot loader did not pass a valid chip ID.
- * Get it from hardware */
+ if (tegra_id.chipid == TEGRA_CHIPID_UNKNOWN)
tegra_get_tegraid_from_hw();
- }
return tegra_id.revision;
}
-static char chippriv[16]; /* Permanent buffer for private string */
-static int __init tegra_bootloader_tegraid(char *str)
-{
- u32 id[5];
- int i = 0;
- char *priv = NULL;
-
- do {
- id[i++] = simple_strtoul(str, &str, 16);
- } while (*str++ && i < ARRAY_SIZE(id));
-
- if (*(str - 1) == '.') {
- strncpy(chippriv, str, sizeof(chippriv) - 1);
- priv = chippriv;
- if (strlen(str) > sizeof(chippriv) - 1)
- pr_err("### tegraid.priv in kernel arg truncated\n");
- }
-
- while (i < ARRAY_SIZE(id))
- id[i++] = 0;
-
- tegra_set_tegraid(id[0], id[1], id[2], id[3], id[4], priv);
- return 0;
-}
-
-static unsigned int get_chip_id(char *val, struct kernel_param *kp)
+static int get_chip_id(char *val, const struct kernel_param *kp)
{
- tegra_chip_id = (unsigned int)tegra_get_chipid();
return param_get_uint(val, kp);
}
-static unsigned int get_chip_rev(char *val, struct kernel_param *kp)
+
+static int get_revision(char *val, const struct kernel_param *kp)
{
- tegra_chip_rev = (unsigned int)tegra_get_revision();
return param_get_uint(val, kp);
}
-module_param_call(tegra_chip_id, NULL, get_chip_id, &tegra_chip_id, 0444);
-__MODULE_PARM_TYPE(tegra_chip_id, "uint");
-module_param_call(tegra_chip_rev, NULL, get_chip_rev, &tegra_chip_rev, 0444);
-__MODULE_PARM_TYPE(tegra_chip_rev, "uint");
+static struct kernel_param_ops tegra_chip_id_ops = {
+ .get = get_chip_id,
+};
+
+static struct kernel_param_ops tegra_revision_ops = {
+ .get = get_revision,
+};
-/* tegraid=chipid.major.minor.netlist.patch[.priv] */
-early_param("tegraid", tegra_bootloader_tegraid);
+module_param_cb(tegra_chip_id, &tegra_chip_id_ops, &tegra_id.chipid, 0444);
+module_param_cb(tegra_chip_rev, &tegra_revision_ops, &tegra_id.revision, 0444);
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
index 219b764..4e28a55 100644
--- a/arch/arm/mach-tegra/headsmp.S
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -66,7 +66,7 @@ ENTRY(tegra_resume)
cpu_id r0
cmp r0, #0 @ CPU0?
- bne cpu_resume @ no
+ bne tegra_cpu_resume_phys @ no
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
@ Clear the flow controller flags for this CPU.
@@ -83,7 +83,9 @@ ENTRY(tegra_resume)
ldr r1, [r0]
orr r1, r1, #1
#if defined(CONFIG_HAVE_ARM_SCU)
- orr r1, r1, #(1 << 3) @ Enabled SCU speculative line fill.
+ orr r1, r1, #(1 << 3) @ Enable SCU speculative line fill.
+ orr r1, r1, #(1 << 5) @ Enable IC standby.
+ orr r1, r1, #(1 << 6) @ Enable SCU standby.
#endif
str r1, [r0]
@@ -92,7 +94,7 @@ ENTRY(tegra_resume)
bl tegra_generic_smc
#endif
- b cpu_resume
+ b tegra_cpu_resume_phys
ENDPROC(tegra_resume)
#endif
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index d4f63af..ab3d4e9 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -6,7 +6,7 @@
* Author:
* Erik Gilling <konkers@google.com>
*
- * Copyright (C) 2010-2012 NVIDIA Corporation
+ * Copyright (C) 2010-2011 NVIDIA Corporation
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -426,6 +426,7 @@ struct tegra_dc_win {
unsigned out_w;
unsigned out_h;
unsigned z;
+ u8 global_alpha;
struct tegra_dc_csc csc;
@@ -505,6 +506,8 @@ struct tegra_dc_platform_data {
struct tegra_dc *tegra_dc_get_dc(unsigned idx);
struct tegra_dc_win *tegra_dc_get_window(struct tegra_dc *dc, unsigned win);
bool tegra_dc_get_connected(struct tegra_dc *);
+bool tegra_dc_hpd(struct tegra_dc *dc);
+
void tegra_dc_blank(struct tegra_dc *dc);
@@ -523,8 +526,6 @@ int tegra_dc_sync_windows(struct tegra_dc_win *windows[], int n);
int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode);
struct fb_videomode;
-int tegra_dc_to_fb_videomode(struct fb_videomode *fbmode,
- const struct tegra_dc_mode *mode);
int tegra_dc_set_fb_mode(struct tegra_dc *dc, const struct fb_videomode *fbmode,
bool stereo_mode);
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
index c6617e9..a0423e9 100644
--- a/arch/arm/mach-tegra/include/mach/dma.h
+++ b/arch/arm/mach-tegra/include/mach/dma.h
@@ -190,6 +190,7 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode,
const char namefmt[], ...);
void tegra_dma_free_channel(struct tegra_dma_channel *ch);
+int tegra_dma_get_channel_id(struct tegra_dma_channel *ch);
/*
* tegra_dma_cancel: Stop the dma and remove all request from pending request
* queue for transfer.
diff --git a/arch/arm/mach-tegra/include/mach/hdmi-audio.h b/arch/arm/mach-tegra/include/mach/hdmi-audio.h
index 7d76069..3555550 100644
--- a/arch/arm/mach-tegra/include/mach/hdmi-audio.h
+++ b/arch/arm/mach-tegra/include/mach/hdmi-audio.h
@@ -42,5 +42,6 @@ enum {
int tegra_hdmi_setup_audio_freq_source(unsigned audio_freq, unsigned audio_source);
int tegra_hdmi_setup_hda_presence(void);
+int tegra_hdmi_audio_null_sample_inject(bool on);
#endif /* __MACH_TEGRA_HDMI_AUDIO_H */
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
index 2b091bf..c6847fb 100644
--- a/arch/arm/mach-tegra/include/mach/io.h
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -82,6 +82,14 @@
#define IO_PPCS_VIRT 0xFE100000
#define IO_PPCS_SIZE SZ_1M
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#define IO_PCIE_PHYS 0x80000000
+#else
+#define IO_PCIE_PHYS 0x00000000
+#endif
+#define IO_PCIE_VIRT 0xFB000000
+#define IO_PCIE_SIZE (SZ_16M * 3)
+
#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))
@@ -102,6 +110,8 @@
IO_TO_VIRT_XLATE((n), IO_SDMMC_PHYS, IO_SDMMC_VIRT) : \
IO_TO_VIRT_BETWEEN((n), IO_PPCS_PHYS, IO_PPCS_SIZE) ? \
IO_TO_VIRT_XLATE((n), IO_PPCS_PHYS, IO_PPCS_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_PCIE_PHYS, IO_PCIE_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_PCIE_PHYS, IO_PCIE_VIRT) : \
0)
#ifndef __ASSEMBLER__
diff --git a/arch/arm/mach-tegra/include/mach/sdhci.h b/arch/arm/mach-tegra/include/mach/sdhci.h
index b48a928..5dc8cd2 100644
--- a/arch/arm/mach-tegra/include/mach/sdhci.h
+++ b/arch/arm/mach-tegra/include/mach/sdhci.h
@@ -28,6 +28,7 @@ struct tegra_sdhci_platform_data {
int pm_flags;
int pm_caps;
unsigned int max_clk_limit;
+ unsigned int ddr_clk_limit;
unsigned int tap_delay;
struct mmc_platform_data mmc_data;
};
diff --git a/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
index bfd61c4..6bea4e5 100644
--- a/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
+++ b/arch/arm/mach-tegra/include/mach/tegra_p1852_pdata.h
@@ -37,6 +37,12 @@ struct codec_info_s {
char *name; /* Name of the Codec-Dai-Link */
enum i2s_data_format i2s_format;
int master; /* Codec is Master or Slave */
+ /* TDM format setttings */
+ int num_slots; /* Number of TDM slots */
+ int slot_width; /* Width of each slot */
+ int rx_mask; /* Number of Rx Enabled slots */
+ int tx_mask; /* Number of Tx Enabled slots */
+
};
struct tegra_p1852_platform_data {
diff --git a/arch/arm/mach-tegra/include/mach/thermal.h b/arch/arm/mach-tegra/include/mach/thermal.h
index ab7b344..6758622 100644
--- a/arch/arm/mach-tegra/include/mach/thermal.h
+++ b/arch/arm/mach-tegra/include/mach/thermal.h
@@ -19,19 +19,17 @@
/* All units in millicelsius */
struct tegra_thermal_data {
- long temp_throttle;
long temp_shutdown;
long temp_offset;
#ifdef CONFIG_TEGRA_EDP_LIMITS
long edp_offset;
long hysteresis_edp;
#endif
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
+ long temp_throttle;
int tc1;
int tc2;
long passive_delay;
-#else
- long hysteresis_throttle;
#endif
};
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
index 47279e1..bcd1084 100644
--- a/arch/arm/mach-tegra/io.c
+++ b/arch/arm/mach-tegra/io.c
@@ -80,6 +80,12 @@ static struct map_desc tegra_io_desc[] __initdata = {
.pfn = __phys_to_pfn(IO_PPCS_PHYS),
.length = IO_PPCS_SIZE,
.type = MT_DEVICE,
+ },
+ {
+ .virtual = IO_PCIE_VIRT,
+ .pfn = __phys_to_pfn(IO_PCIE_PHYS),
+ .length = IO_PCIE_SIZE,
+ .type = MT_DEVICE,
}
};
diff --git a/arch/arm/mach-tegra/iovmm-smmu.c b/arch/arm/mach-tegra/iovmm-smmu.c
index 170afd1..6cdeb74 100644
--- a/arch/arm/mach-tegra/iovmm-smmu.c
+++ b/arch/arm/mach-tegra/iovmm-smmu.c
@@ -310,10 +310,14 @@ struct smmu_device {
/*
* Register image savers for suspend/resume
*/
- unsigned long translation_enable_0_0;
- unsigned long translation_enable_1_0;
- unsigned long translation_enable_2_0;
- unsigned long asid_security_0;
+ unsigned long config_0; /* Secure reg */
+ unsigned long tlb_config_0;
+ unsigned long ptc_config_0;
+ unsigned long ptb_asid_0;
+ unsigned long translation_enable_0_0; /* Secure reg */
+ unsigned long translation_enable_1_0; /* Secure reg */
+ unsigned long translation_enable_2_0; /* Secure reg */
+ unsigned long asid_security_0; /* Secure reg */
unsigned long lowest_asid; /* Variables for hardware testing */
unsigned long debug_asid;
@@ -335,13 +339,13 @@ struct smmu_device {
* must have these read-back to ensure the APB/AHB bus transaction is
* complete before initiating activity on the PPSB block.
*/
-#define FLUSH_SMMU_REGS(smmu) (void)readl((smmu)->regs + MC_SMMU_CONFIG_0)
+#define FLUSH_SMMU_REGS(smmu) (void)readl((smmu)->regs + MC_SMMU_PTB_DATA_0)
/*
* Flush all TLB entries and all PTC entries
* Caller must lock smmu
*/
-static void smmu_flush_regs(struct smmu_device *smmu, int enable)
+static void smmu_flush_regs(struct smmu_device *smmu)
{
writel(MC_SMMU_PTC_FLUSH_0_PTC_FLUSH_TYPE_ALL,
smmu->regs + MC_SMMU_PTC_FLUSH_0);
@@ -349,10 +353,6 @@ static void smmu_flush_regs(struct smmu_device *smmu, int enable)
writel(MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_VA_MATCH_ALL |
MC_SMMU_TLB_FLUSH_0_TLB_FLUSH_ASID_MATCH_disable,
smmu->regs + MC_SMMU_TLB_FLUSH_0);
-
- if (enable)
- writel(MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE,
- smmu->regs + MC_SMMU_CONFIG_0);
FLUSH_SMMU_REGS(smmu);
}
@@ -388,14 +388,14 @@ static void smmu_setup_regs(struct smmu_device *smmu)
smmu->regs + MC_SMMU_TRANSLATION_ENABLE_1_0);
writel(smmu->translation_enable_2_0,
smmu->regs + MC_SMMU_TRANSLATION_ENABLE_2_0);
- writel(smmu->asid_security_0,
- smmu->regs + MC_SMMU_ASID_SECURITY_0);
- writel(MC_SMMU_TLB_CONFIG_0_RESET_VAL,
- smmu->regs + MC_SMMU_TLB_CONFIG_0);
- writel(MC_SMMU_PTC_CONFIG_0_RESET_VAL,
- smmu->regs + MC_SMMU_PTC_CONFIG_0);
-
- smmu_flush_regs(smmu, 1);
+ writel(smmu->asid_security_0, smmu->regs + MC_SMMU_ASID_SECURITY_0);
+ writel(smmu->ptb_asid_0, smmu->regs + MC_SMMU_PTB_ASID_0);
+ writel(smmu->ptc_config_0, smmu->regs + MC_SMMU_PTC_CONFIG_0);
+ writel(smmu->tlb_config_0, smmu->regs + MC_SMMU_TLB_CONFIG_0);
+ writel(smmu->config_0, smmu->regs + MC_SMMU_CONFIG_0);
+
+ smmu_flush_regs(smmu);
+
writel(
readl(smmu->regs_ahbarb + AHB_ARBITRATION_XBAR_CTRL_0) |
(AHB_ARBITRATION_XBAR_CTRL_0_SMMU_INIT_DONE_DONE <<
@@ -408,6 +408,10 @@ static int smmu_suspend(struct tegra_iovmm_device *dev)
struct smmu_device *smmu =
container_of(dev, struct smmu_device, iovmm_dev);
+ smmu->config_0 = readl(smmu->regs + MC_SMMU_CONFIG_0);
+ smmu->tlb_config_0 = readl(smmu->regs + MC_SMMU_TLB_CONFIG_0);
+ smmu->ptc_config_0 = readl(smmu->regs + MC_SMMU_PTC_CONFIG_0);
+ smmu->ptb_asid_0 = readl(smmu->regs + MC_SMMU_PTB_ASID_0);
smmu->translation_enable_0_0 =
readl(smmu->regs + MC_SMMU_TRANSLATION_ENABLE_0_0);
smmu->translation_enable_1_0 =
@@ -691,10 +695,8 @@ static void smmu_unmap(struct tegra_iovmm_domain *domain,
flush_ptc_and_tlb(as->smmu, as, addr, pte,
page, 0);
kunmap(page);
- if (!--(*pte_counter) && decommit) {
+ if (!--(*pte_counter) && decommit)
free_ptbl(as, addr);
- smmu_flush_regs(as->smmu, 0);
- }
}
}
addr += SMMU_PAGE_SIZE;
@@ -703,7 +705,7 @@ static void smmu_unmap(struct tegra_iovmm_domain *domain,
}
static void smmu_map_pfn(struct tegra_iovmm_domain *domain,
- struct tegra_iovmm_area *iovma, tegra_iovmm_addr_t addr,
+ struct tegra_iovmm_area *iovma, unsigned long addr,
unsigned long pfn)
{
struct smmu_as *as = container_of(domain, struct smmu_as, domain);
@@ -966,10 +968,14 @@ static int smmu_probe(struct platform_device *pdev)
goto fail;
}
+ smmu->config_0 = MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE;
+ smmu->tlb_config_0 = MC_SMMU_TLB_CONFIG_0_RESET_VAL;
+ smmu->ptc_config_0 = MC_SMMU_PTC_CONFIG_0_RESET_VAL;
+ smmu->ptb_asid_0 = 0;
smmu->translation_enable_0_0 = ~0;
smmu->translation_enable_1_0 = ~0;
smmu->translation_enable_2_0 = ~0;
- smmu->asid_security_0 = 0;
+ smmu->asid_security_0 = 0;
memcpy(smmu->hwc_state, smmu_hwc_state_init, sizeof(smmu->hwc_state));
diff --git a/arch/arm/mach-tegra/p852/board-p852-panel.c b/arch/arm/mach-tegra/p852/board-p852-panel.c
index c47032d..bcf9f4a 100644
--- a/arch/arm/mach-tegra/p852/board-p852-panel.c
+++ b/arch/arm/mach-tegra/p852/board-p852-panel.c
@@ -25,7 +25,7 @@
#include <linux/nvhost.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/dc.h>
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index b98d489..1c4ee1b 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -540,7 +540,7 @@ static void __devinit tegra_pcie_relax_enable(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
-static void __init tegra_pcie_preinit(void)
+static void tegra_pcie_preinit(void)
{
pcie_io_space.name = "PCIe I/O Space";
pcie_io_space.start = PCIBIOS_MIN_IO;
@@ -1099,13 +1099,14 @@ static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
}
retry:
- /* Pulse the PEX reset */
- reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
- afi_writel(reg, reset_reg);
- reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
- afi_writel(reg, reset_reg);
+ if (--retries) {
+ /* Pulse the PEX reset */
+ reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
+ afi_writel(reg, reset_reg);
+ reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
+ afi_writel(reg, reset_reg);
+ }
- retries--;
} while (retries);
return false;
@@ -1201,9 +1202,13 @@ static int tegra_pci_probe(struct platform_device *pdev)
static int tegra_pci_suspend(struct device *dev)
{
+ int ret = 0;
struct pci_dev *pdev = NULL;
int i, size, ndev = 0;
+ if (!tegra_pcie.num_ports)
+ return ret;
+
for_each_pci_dev(pdev) {
/* save state of pcie devices before powering off regulators */
pci_save_state(pdev);
@@ -1243,10 +1248,12 @@ static int tegra_pci_resume_noirq(struct device *dev)
static int tegra_pci_resume(struct device *dev)
{
- int ret;
+ int ret = 0;
int i, size, ndev = 0;
struct pci_dev *pdev = NULL;
+ if (!tegra_pcie.num_ports)
+ return ret;
ret = tegra_pcie_power_on();
tegra_pcie_enable_controller();
tegra_pcie_setup_translations();
diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c
index 3a39f45..32e5542 100644
--- a/arch/arm/mach-tegra/pinmux-t2-tables.c
+++ b/arch/arm/mach-tegra/pinmux-t2-tables.c
@@ -195,9 +195,9 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
PINGROUP(LM0, PW0, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 24, 0x90, 26, 0xAC, 22),\
PINGROUP(LM1, PW1, LCD, DISPLAYA, DISPLAYB, RSVD, CRT, RSVD3, 0x1C, 25, 0x90, 28, 0xAC, 22),\
PINGROUP(LPP, PM7, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 8, 0x98, 14, 0xAC, 18),\
- PINGROUP(LPW0, PB2, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 3, 0x90, 0, 0xAC, 20),\
+ PINGROUP(LPW0, PB2, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYB, 0x20, 3, 0x90, 0, 0xAC, 20),\
PINGROUP(LPW1, PC1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 4, 0x90, 2, 0xAC, 20),\
- PINGROUP(LPW2, PC6, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 5, 0x90, 4, 0xAC, 20),\
+ PINGROUP(LPW2, PC6, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYB, 0x20, 5, 0x90, 4, 0xAC, 20),\
PINGROUP(LSC0, PB3, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 27, 0x90, 18, 0xAC, 22),\
PINGROUP(LSC1, PZ3, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 28, 0x90, 20, 0xAC, 20),\
PINGROUP(LSCK, PZ4, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 29, 0x90, 16, 0xAC, 20),\
diff --git a/arch/arm/mach-tegra/pinmux-t3-tables.c b/arch/arm/mach-tegra/pinmux-t3-tables.c
index 282a34b..5e50fed 100644
--- a/arch/arm/mach-tegra/pinmux-t3-tables.c
+++ b/arch/arm/mach-tegra/pinmux-t3-tables.c
@@ -140,166 +140,166 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
#define PINGROUPS \
/* NAME GPIO VDD f0 f1 f2 f3 fSafe io reg */\
- PINGROUP(ULPI_DATA0, PO1, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3000),\
- PINGROUP(ULPI_DATA1, PO2, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3004),\
- PINGROUP(ULPI_DATA2, PO3, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3008),\
- PINGROUP(ULPI_DATA3, PO4, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x300c),\
- PINGROUP(ULPI_DATA4, PO5, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3010),\
- PINGROUP(ULPI_DATA5, PO6, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3014),\
- PINGROUP(ULPI_DATA6, PO7, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3018),\
- PINGROUP(ULPI_DATA7, PO0, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x301c),\
- PINGROUP(ULPI_CLK, PY0, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3020),\
- PINGROUP(ULPI_DIR, PY1, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3024),\
- PINGROUP(ULPI_NXT, PY2, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3028),\
- PINGROUP(ULPI_STP, PY3, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x302c),\
- PINGROUP(DAP3_FS, PP0, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3030),\
- PINGROUP(DAP3_DIN, PP1, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3034),\
- PINGROUP(DAP3_DOUT, PP2, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3038),\
- PINGROUP(DAP3_SCLK, PP3, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x303c),\
+ PINGROUP(ULPI_DATA0, PO1, BB, SPI3, HSI, UARTA, ULPI, ULPI, INPUT, 0x3000),\
+ PINGROUP(ULPI_DATA1, PO2, BB, SPI3, HSI, UARTA, ULPI, ULPI, INPUT, 0x3004),\
+ PINGROUP(ULPI_DATA2, PO3, BB, SPI3, HSI, UARTA, ULPI, ULPI, INPUT, 0x3008),\
+ PINGROUP(ULPI_DATA3, PO4, BB, SPI3, HSI, UARTA, ULPI, ULPI, INPUT, 0x300c),\
+ PINGROUP(ULPI_DATA4, PO5, BB, SPI2, HSI, UARTA, ULPI, ULPI, INPUT, 0x3010),\
+ PINGROUP(ULPI_DATA5, PO6, BB, SPI2, HSI, UARTA, ULPI, ULPI, INPUT, 0x3014),\
+ PINGROUP(ULPI_DATA6, PO7, BB, SPI2, HSI, UARTA, ULPI, ULPI, INPUT, 0x3018),\
+ PINGROUP(ULPI_DATA7, PO0, BB, SPI2, HSI, UARTA, ULPI, ULPI, INPUT, 0x301c),\
+ PINGROUP(ULPI_CLK, PY0, BB, SPI1, RSVD, UARTD, ULPI, ULPI, INPUT, 0x3020),\
+ PINGROUP(ULPI_DIR, PY1, BB, SPI1, RSVD, UARTD, ULPI, ULPI, INPUT, 0x3024),\
+ PINGROUP(ULPI_NXT, PY2, BB, SPI1, RSVD, UARTD, ULPI, ULPI, INPUT, 0x3028),\
+ PINGROUP(ULPI_STP, PY3, BB, SPI1, RSVD, UARTD, ULPI, ULPI, INPUT, 0x302c),\
+ PINGROUP(DAP3_FS, PP0, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, I2S2, INPUT, 0x3030),\
+ PINGROUP(DAP3_DIN, PP1, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, I2S2, INPUT, 0x3034),\
+ PINGROUP(DAP3_DOUT, PP2, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, I2S2, INPUT, 0x3038),\
+ PINGROUP(DAP3_SCLK, PP3, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, I2S2, INPUT, 0x303c),\
PINGROUP(GPIO_PV0, PV0, BB, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3040),\
PINGROUP(GPIO_PV1, PV1, BB, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3044),\
- PINGROUP(SDMMC1_CLK, PZ0, SDMMC1, SDMMC1, RSVD1, RSVD2, INVALID, RSVD, INPUT, 0x3048),\
- PINGROUP(SDMMC1_CMD, PZ1, SDMMC1, SDMMC1, RSVD1, RSVD2, INVALID, RSVD, INPUT, 0x304c),\
- PINGROUP(SDMMC1_DAT3, PY4, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3050),\
- PINGROUP(SDMMC1_DAT2, PY5, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3054),\
- PINGROUP(SDMMC1_DAT1, PY6, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3058),\
- PINGROUP(SDMMC1_DAT0, PY7, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x305c),\
+ PINGROUP(SDMMC1_CLK, PZ0, SDMMC1, SDMMC1, RSVD1, RSVD2, INVALID, SDMMC1, INPUT, 0x3048),\
+ PINGROUP(SDMMC1_CMD, PZ1, SDMMC1, SDMMC1, RSVD1, RSVD2, INVALID, SDMMC1, INPUT, 0x304c),\
+ PINGROUP(SDMMC1_DAT3, PY4, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, SDMMC1, INPUT, 0x3050),\
+ PINGROUP(SDMMC1_DAT2, PY5, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, SDMMC1, INPUT, 0x3054),\
+ PINGROUP(SDMMC1_DAT1, PY6, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, SDMMC1, INPUT, 0x3058),\
+ PINGROUP(SDMMC1_DAT0, PY7, SDMMC1, SDMMC1, RSVD1, UARTE, INVALID, SDMMC1, INPUT, 0x305c),\
PINGROUP(GPIO_PV2, PV2, SDMMC1, OWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3060),\
PINGROUP(GPIO_PV3, PV3, SDMMC1, INVALID, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3064),\
- PINGROUP(CLK2_OUT, PW5, SDMMC1, EXTPERIPH2, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3068),\
- PINGROUP(CLK2_REQ, PCC5, SDMMC1, DAP, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x306c),\
- PINGROUP(LCD_PWR1, PC1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3070),\
- PINGROUP(LCD_PWR2, PC6, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3074),\
- PINGROUP(LCD_SDIN, PZ2, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD, RSVD, OUTPUT, 0x3078),\
- PINGROUP(LCD_SDOUT, PN5, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x307c),\
- PINGROUP(LCD_WR_N, PZ3, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3080),\
- PINGROUP(LCD_CS0_N, PN4, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD, RSVD, OUTPUT, 0x3084),\
- PINGROUP(LCD_DC0, PN6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3088),\
- PINGROUP(LCD_SCK, PZ4, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x308c),\
- PINGROUP(LCD_PWR0, PB2, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3090),\
- PINGROUP(LCD_PCLK, PB3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3094),\
- PINGROUP(LCD_DE, PJ1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3098),\
- PINGROUP(LCD_HSYNC, PJ3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x309c),\
- PINGROUP(LCD_VSYNC, PJ4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a0),\
- PINGROUP(LCD_D0, PE0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a4),\
- PINGROUP(LCD_D1, PE1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a8),\
- PINGROUP(LCD_D2, PE2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30ac),\
- PINGROUP(LCD_D3, PE3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b0),\
- PINGROUP(LCD_D4, PE4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b4),\
- PINGROUP(LCD_D5, PE5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b8),\
- PINGROUP(LCD_D6, PE6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30bc),\
- PINGROUP(LCD_D7, PE7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c0),\
- PINGROUP(LCD_D8, PF0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c4),\
- PINGROUP(LCD_D9, PF1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c8),\
- PINGROUP(LCD_D10, PF2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30cc),\
- PINGROUP(LCD_D11, PF3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d0),\
- PINGROUP(LCD_D12, PF4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d4),\
- PINGROUP(LCD_D13, PF5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d8),\
- PINGROUP(LCD_D14, PF6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30dc),\
- PINGROUP(LCD_D15, PF7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e0),\
- PINGROUP(LCD_D16, PM0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e4),\
- PINGROUP(LCD_D17, PM1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e8),\
- PINGROUP(LCD_D18, PM2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30ec),\
- PINGROUP(LCD_D19, PM3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f0),\
- PINGROUP(LCD_D20, PM4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f4),\
- PINGROUP(LCD_D21, PM5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f8),\
- PINGROUP(LCD_D22, PM6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30fc),\
- PINGROUP(LCD_D23, PM7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3100),\
- PINGROUP(LCD_CS1_N, PW0, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD2, RSVD, OUTPUT, 0x3104),\
- PINGROUP(LCD_M1, PW1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3108),\
- PINGROUP(LCD_DC1, PD2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x310c),\
+ PINGROUP(CLK2_OUT, PW5, SDMMC1, EXTPERIPH2, RSVD1, RSVD2, RSVD3, EXTPERIPH2, INPUT, 0x3068),\
+ PINGROUP(CLK2_REQ, PCC5, SDMMC1, DAP, RSVD1, RSVD2, RSVD3, DAP, INPUT, 0x306c),\
+ PINGROUP(LCD_PWR1, PC1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x3070),\
+ PINGROUP(LCD_PWR2, PC6, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, DISPLAYA, OUTPUT, 0x3074),\
+ PINGROUP(LCD_SDIN, PZ2, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD, DISPLAYA, OUTPUT, 0x3078),\
+ PINGROUP(LCD_SDOUT, PN5, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, DISPLAYA, OUTPUT, 0x307c),\
+ PINGROUP(LCD_WR_N, PZ3, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, DISPLAYA, OUTPUT, 0x3080),\
+ PINGROUP(LCD_CS0_N, PN4, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD, DISPLAYA, OUTPUT, 0x3084),\
+ PINGROUP(LCD_DC0, PN6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x3088),\
+ PINGROUP(LCD_SCK, PZ4, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, DISPLAYA, OUTPUT, 0x308c),\
+ PINGROUP(LCD_PWR0, PB2, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, DISPLAYA, OUTPUT, 0x3090),\
+ PINGROUP(LCD_PCLK, PB3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x3094),\
+ PINGROUP(LCD_DE, PJ1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x3098),\
+ PINGROUP(LCD_HSYNC, PJ3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x309c),\
+ PINGROUP(LCD_VSYNC, PJ4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30a0),\
+ PINGROUP(LCD_D0, PE0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30a4),\
+ PINGROUP(LCD_D1, PE1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30a8),\
+ PINGROUP(LCD_D2, PE2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30ac),\
+ PINGROUP(LCD_D3, PE3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30b0),\
+ PINGROUP(LCD_D4, PE4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30b4),\
+ PINGROUP(LCD_D5, PE5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30b8),\
+ PINGROUP(LCD_D6, PE6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30bc),\
+ PINGROUP(LCD_D7, PE7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30c0),\
+ PINGROUP(LCD_D8, PF0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30c4),\
+ PINGROUP(LCD_D9, PF1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30c8),\
+ PINGROUP(LCD_D10, PF2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30cc),\
+ PINGROUP(LCD_D11, PF3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30d0),\
+ PINGROUP(LCD_D12, PF4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30d4),\
+ PINGROUP(LCD_D13, PF5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30d8),\
+ PINGROUP(LCD_D14, PF6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30dc),\
+ PINGROUP(LCD_D15, PF7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30e0),\
+ PINGROUP(LCD_D16, PM0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30e4),\
+ PINGROUP(LCD_D17, PM1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30e8),\
+ PINGROUP(LCD_D18, PM2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30ec),\
+ PINGROUP(LCD_D19, PM3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30f0),\
+ PINGROUP(LCD_D20, PM4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30f4),\
+ PINGROUP(LCD_D21, PM5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30f8),\
+ PINGROUP(LCD_D22, PM6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x30fc),\
+ PINGROUP(LCD_D23, PM7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x3100),\
+ PINGROUP(LCD_CS1_N, PW0, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD2, DISPLAYA, OUTPUT, 0x3104),\
+ PINGROUP(LCD_M1, PW1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x3108),\
+ PINGROUP(LCD_DC1, PD2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, DISPLAYA, OUTPUT, 0x310c),\
PINGROUP(HDMI_INT, PN7, LCD, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3110),\
- PINGROUP(DDC_SCL, PV4, LCD, I2C4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3114),\
- PINGROUP(DDC_SDA, PV5, LCD, I2C4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3118),\
- PINGROUP(CRT_HSYNC, PV6, LCD, CRT, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x311c),\
- PINGROUP(CRT_VSYNC, PV7, LCD, CRT, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3120),\
- PINGROUP(VI_D0, PT4, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3124),\
- PINGROUP(VI_D1, PD5, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3128),\
- PINGROUP(VI_D2, PL0, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x312c),\
- PINGROUP(VI_D3, PL1, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3130),\
- PINGROUP(VI_D4, PL2, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3134),\
- PINGROUP(VI_D5, PL3, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3138),\
- PINGROUP(VI_D6, PL4, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x313c),\
- PINGROUP(VI_D7, PL5, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3140),\
- PINGROUP(VI_D8, PL6, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3144),\
- PINGROUP(VI_D9, PL7, VI, INVALID, SDMMC2, VI, RSVD1, RSVD, INPUT, 0x3148),\
- PINGROUP(VI_D10, PT2, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x314c),\
- PINGROUP(VI_D11, PT3, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3150),\
- PINGROUP(VI_PCLK, PT0, VI, RSVD1, SDMMC2, VI, RSVD2, RSVD, INPUT, 0x3154),\
+ PINGROUP(DDC_SCL, PV4, LCD, I2C4, RSVD1, RSVD2, RSVD3, I2C4, INPUT, 0x3114),\
+ PINGROUP(DDC_SDA, PV5, LCD, I2C4, RSVD1, RSVD2, RSVD3, I2C4, INPUT, 0x3118),\
+ PINGROUP(CRT_HSYNC, PV6, LCD, CRT, RSVD1, RSVD2, RSVD3, CRT, INPUT, 0x311c),\
+ PINGROUP(CRT_VSYNC, PV7, LCD, CRT, RSVD1, RSVD2, RSVD3, CRT, INPUT, 0x3120),\
+ PINGROUP(VI_D0, PT4, VI, INVALID, RSVD1, VI, RSVD2, VI, INPUT, 0x3124),\
+ PINGROUP(VI_D1, PD5, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x3128),\
+ PINGROUP(VI_D2, PL0, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x312c),\
+ PINGROUP(VI_D3, PL1, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x3130),\
+ PINGROUP(VI_D4, PL2, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x3134),\
+ PINGROUP(VI_D5, PL3, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x3138),\
+ PINGROUP(VI_D6, PL4, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x313c),\
+ PINGROUP(VI_D7, PL5, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x3140),\
+ PINGROUP(VI_D8, PL6, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x3144),\
+ PINGROUP(VI_D9, PL7, VI, INVALID, SDMMC2, VI, RSVD1, VI, INPUT, 0x3148),\
+ PINGROUP(VI_D10, PT2, VI, INVALID, RSVD1, VI, RSVD2, VI, INPUT, 0x314c),\
+ PINGROUP(VI_D11, PT3, VI, INVALID, RSVD1, VI, RSVD2, VI, INPUT, 0x3150),\
+ PINGROUP(VI_PCLK, PT0, VI, RSVD1, SDMMC2, VI, RSVD2, VI, INPUT, 0x3154),\
PINGROUP(VI_MCLK, PT1, VI, INVALID, INVALID, INVALID, VI, RSVD, INPUT, 0x3158),\
- PINGROUP(VI_VSYNC, PD6, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x315c),\
- PINGROUP(VI_HSYNC, PD7, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3160),\
- PINGROUP(UART2_RXD, PC3, UART, IRDA, SPDIF, UARTA, SPI4, RSVD, INPUT, 0x3164),\
- PINGROUP(UART2_TXD, PC2, UART, IRDA, SPDIF, UARTA, SPI4, RSVD, INPUT, 0x3168),\
- PINGROUP(UART2_RTS_N, PJ6, UART, UARTA, UARTB, GMI, SPI4, RSVD, INPUT, 0x316c),\
- PINGROUP(UART2_CTS_N, PJ5, UART, UARTA, UARTB, GMI, SPI4, RSVD, INPUT, 0x3170),\
- PINGROUP(UART3_TXD, PW6, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x3174),\
- PINGROUP(UART3_RXD, PW7, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x3178),\
- PINGROUP(UART3_CTS_N, PA1, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x317c),\
- PINGROUP(UART3_RTS_N, PC0, UART, UARTC, PWM0, GMI, RSVD2, RSVD, INPUT, 0x3180),\
- PINGROUP(GPIO_PU0, PU0, UART, OWR, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3184),\
- PINGROUP(GPIO_PU1, PU1, UART, RSVD1, UARTA, GMI, RSVD2, RSVD, INPUT, 0x3188),\
- PINGROUP(GPIO_PU2, PU2, UART, RSVD1, UARTA, GMI, RSVD2, RSVD, INPUT, 0x318c),\
- PINGROUP(GPIO_PU3, PU3, UART, PWM0, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3190),\
- PINGROUP(GPIO_PU4, PU4, UART, PWM1, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3194),\
- PINGROUP(GPIO_PU5, PU5, UART, PWM2, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3198),\
- PINGROUP(GPIO_PU6, PU6, UART, PWM3, UARTA, GMI, RSVD1, RSVD, INPUT, 0x319c),\
- PINGROUP(GEN1_I2C_SDA, PC5, UART, I2C1, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31a0),\
- PINGROUP(GEN1_I2C_SCL, PC4, UART, I2C1, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31a4),\
- PINGROUP(DAP4_FS, PP4, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31a8),\
- PINGROUP(DAP4_DIN, PP5, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31ac),\
- PINGROUP(DAP4_DOUT, PP6, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31b0),\
- PINGROUP(DAP4_SCLK, PP7, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31b4),\
- PINGROUP(CLK3_OUT, PEE0, UART, EXTPERIPH3, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31b8),\
- PINGROUP(CLK3_REQ, PEE1, UART, DEV3, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31bc),\
- PINGROUP(GMI_WP_N, PC7, GMI, RSVD1, NAND, GMI, GMI_ALT, RSVD, INPUT, 0x31c0),\
- PINGROUP(GMI_IORDY, PI5, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31c4),\
- PINGROUP(GMI_WAIT, PI7, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31c8),\
- PINGROUP(GMI_ADV_N, PK0, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31cc),\
- PINGROUP(GMI_CLK, PK1, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31d0),\
- PINGROUP(GMI_CS0_N, PJ0, GMI, RSVD1, NAND, GMI, DTV, RSVD, INPUT, 0x31d4),\
- PINGROUP(GMI_CS1_N, PJ2, GMI, RSVD1, NAND, GMI, DTV, RSVD, INPUT, 0x31d8),\
- PINGROUP(GMI_CS2_N, PK3, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31dc),\
- PINGROUP(GMI_CS3_N, PK4, GMI, RSVD1, NAND, GMI, GMI_ALT, RSVD, INPUT, 0x31e0),\
- PINGROUP(GMI_CS4_N, PK2, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31e4),\
- PINGROUP(GMI_CS6_N, PI3, GMI, NAND, NAND_ALT, GMI, SATA, RSVD, INPUT, 0x31e8),\
- PINGROUP(GMI_CS7_N, PI6, GMI, NAND, NAND_ALT, GMI, GMI_ALT, RSVD, INPUT, 0x31ec),\
- PINGROUP(GMI_AD0, PG0, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f0),\
- PINGROUP(GMI_AD1, PG1, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f4),\
- PINGROUP(GMI_AD2, PG2, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f8),\
- PINGROUP(GMI_AD3, PG3, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31fc),\
- PINGROUP(GMI_AD4, PG4, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3200),\
- PINGROUP(GMI_AD5, PG5, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3204),\
- PINGROUP(GMI_AD6, PG6, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3208),\
- PINGROUP(GMI_AD7, PG7, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x320c),\
- PINGROUP(GMI_AD8, PH0, GMI, PWM0, NAND, GMI, RSVD2, RSVD, INPUT, 0x3210),\
- PINGROUP(GMI_AD9, PH1, GMI, PWM1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3214),\
- PINGROUP(GMI_AD10, PH2, GMI, PWM2, NAND, GMI, RSVD2, RSVD, INPUT, 0x3218),\
- PINGROUP(GMI_AD11, PH3, GMI, PWM3, NAND, GMI, RSVD2, RSVD, INPUT, 0x321c),\
- PINGROUP(GMI_AD12, PH4, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3220),\
- PINGROUP(GMI_AD13, PH5, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3224),\
- PINGROUP(GMI_AD14, PH6, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3228),\
- PINGROUP(GMI_AD15, PH7, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x322c),\
- PINGROUP(GMI_A16, PJ7, GMI, UARTD, SPI4, GMI, GMI_ALT, RSVD, INPUT, 0x3230),\
- PINGROUP(GMI_A17, PB0, GMI, UARTD, SPI4, GMI, DTV, RSVD, INPUT, 0x3234),\
- PINGROUP(GMI_A18, PB1, GMI, UARTD, SPI4, GMI, DTV, RSVD, INPUT, 0x3238),\
- PINGROUP(GMI_A19, PK7, GMI, UARTD, SPI4, GMI, RSVD3, RSVD, INPUT, 0x323c),\
- PINGROUP(GMI_WR_N, PI0, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3240),\
- PINGROUP(GMI_OE_N, PI1, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3244),\
- PINGROUP(GMI_DQS, PI2, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3248),\
- PINGROUP(GMI_RST_N, PI4, GMI, NAND, NAND_ALT, GMI, RSVD3, RSVD, INPUT, 0x324c),\
- PINGROUP(GEN2_I2C_SCL, PT5, GMI, I2C2, INVALID, GMI, RSVD3, RSVD, INPUT, 0x3250),\
- PINGROUP(GEN2_I2C_SDA, PT6, GMI, I2C2, INVALID, GMI, RSVD3, RSVD, INPUT, 0x3254),\
- PINGROUP(SDMMC4_CLK, PCC4, SDMMC4, INVALID, NAND, GMI, SDMMC4, RSVD, INPUT, 0x3258),\
- PINGROUP(SDMMC4_CMD, PT7, SDMMC4, I2C3, NAND, GMI, SDMMC4, RSVD, INPUT, 0x325c),\
- PINGROUP(SDMMC4_DAT0, PAA0, SDMMC4, UARTE, SPI3, GMI, SDMMC4, RSVD, INPUT, 0x3260),\
- PINGROUP(SDMMC4_DAT1, PAA1, SDMMC4, UARTE, SPI3, GMI, SDMMC4, RSVD, INPUT, 0x3264),\
- PINGROUP(SDMMC4_DAT2, PAA2, SDMMC4, UARTE, SPI3, GMI, SDMMC4, RSVD, INPUT, 0x3268),\
- PINGROUP(SDMMC4_DAT3, PAA3, SDMMC4, UARTE, SPI3, GMI, SDMMC4, RSVD, INPUT, 0x326c),\
- PINGROUP(SDMMC4_DAT4, PAA4, SDMMC4, I2C3, I2S4, GMI, SDMMC4, RSVD, INPUT, 0x3270),\
- PINGROUP(SDMMC4_DAT5, PAA5, SDMMC4, VGP3, I2S4, GMI, SDMMC4, RSVD, INPUT, 0x3274),\
- PINGROUP(SDMMC4_DAT6, PAA6, SDMMC4, VGP4, I2S4, GMI, SDMMC4, RSVD, INPUT, 0x3278),\
- PINGROUP(SDMMC4_DAT7, PAA7, SDMMC4, VGP5, I2S4, GMI, SDMMC4, RSVD, INPUT, 0x327c),\
+ PINGROUP(VI_VSYNC, PD6, VI, INVALID, RSVD1, VI, RSVD2, VI, INPUT, 0x315c),\
+ PINGROUP(VI_HSYNC, PD7, VI, INVALID, RSVD1, VI, RSVD2, VI, INPUT, 0x3160),\
+ PINGROUP(UART2_RXD, PC3, UART, IRDA, SPDIF, UARTA, SPI4, IRDA, INPUT, 0x3164),\
+ PINGROUP(UART2_TXD, PC2, UART, IRDA, SPDIF, UARTA, SPI4, IRDA, INPUT, 0x3168),\
+ PINGROUP(UART2_RTS_N, PJ6, UART, UARTA, UARTB, GMI, SPI4, UARTB, INPUT, 0x316c),\
+ PINGROUP(UART2_CTS_N, PJ5, UART, UARTA, UARTB, GMI, SPI4, UARTB, INPUT, 0x3170),\
+ PINGROUP(UART3_TXD, PW6, UART, UARTC, RSVD1, GMI, RSVD2, UARTC, INPUT, 0x3174),\
+ PINGROUP(UART3_RXD, PW7, UART, UARTC, RSVD1, GMI, RSVD2, UARTC, INPUT, 0x3178),\
+ PINGROUP(UART3_CTS_N, PA1, UART, UARTC, RSVD1, GMI, RSVD2, UARTC, INPUT, 0x317c),\
+ PINGROUP(UART3_RTS_N, PC0, UART, UARTC, PWM0, GMI, RSVD2, UARTC, INPUT, 0x3180),\
+ PINGROUP(GPIO_PU0, PU0, UART, OWR, UARTA, GMI, RSVD1, GMI, INPUT, 0x3184),\
+ PINGROUP(GPIO_PU1, PU1, UART, RSVD1, UARTA, GMI, RSVD2, GMI, INPUT, 0x3188),\
+ PINGROUP(GPIO_PU2, PU2, UART, RSVD1, UARTA, GMI, RSVD2, GMI, INPUT, 0x318c),\
+ PINGROUP(GPIO_PU3, PU3, UART, PWM0, UARTA, GMI, RSVD1, GMI, INPUT, 0x3190),\
+ PINGROUP(GPIO_PU4, PU4, UART, PWM1, UARTA, GMI, RSVD1, GMI, INPUT, 0x3194),\
+ PINGROUP(GPIO_PU5, PU5, UART, PWM2, UARTA, GMI, RSVD1, GMI, INPUT, 0x3198),\
+ PINGROUP(GPIO_PU6, PU6, UART, PWM3, UARTA, GMI, RSVD1, GMI, INPUT, 0x319c),\
+ PINGROUP(GEN1_I2C_SDA, PC5, UART, I2C1, RSVD1, RSVD2, RSVD3, I2C1, INPUT, 0x31a0),\
+ PINGROUP(GEN1_I2C_SCL, PC4, UART, I2C1, RSVD1, RSVD2, RSVD3, I2C1, INPUT, 0x31a4),\
+ PINGROUP(DAP4_FS, PP4, UART, I2S3, RSVD1, GMI, RSVD2, I2S3, INPUT, 0x31a8),\
+ PINGROUP(DAP4_DIN, PP5, UART, I2S3, RSVD1, GMI, RSVD2, I2S3, INPUT, 0x31ac),\
+ PINGROUP(DAP4_DOUT, PP6, UART, I2S3, RSVD1, GMI, RSVD2, I2S3, INPUT, 0x31b0),\
+ PINGROUP(DAP4_SCLK, PP7, UART, I2S3, RSVD1, GMI, RSVD2, I2S3, INPUT, 0x31b4),\
+ PINGROUP(CLK3_OUT, PEE0, UART, EXTPERIPH3, RSVD1, RSVD2, RSVD3, EXTPERIPH3, INPUT, 0x31b8),\
+ PINGROUP(CLK3_REQ, PEE1, UART, DEV3, RSVD1, RSVD2, RSVD3, DEV3, INPUT, 0x31bc),\
+ PINGROUP(GMI_WP_N, PC7, GMI, RSVD1, NAND, GMI, GMI_ALT, GMI, INPUT, 0x31c0),\
+ PINGROUP(GMI_IORDY, PI5, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31c4),\
+ PINGROUP(GMI_WAIT, PI7, GMI, RSVD1, NAND, GMI, RSVD2, NAND, INPUT, 0x31c8),\
+ PINGROUP(GMI_ADV_N, PK0, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31cc),\
+ PINGROUP(GMI_CLK, PK1, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31d0),\
+ PINGROUP(GMI_CS0_N, PJ0, GMI, RSVD1, NAND, GMI, DTV, GMI, INPUT, 0x31d4),\
+ PINGROUP(GMI_CS1_N, PJ2, GMI, RSVD1, NAND, GMI, DTV, GMI, INPUT, 0x31d8),\
+ PINGROUP(GMI_CS2_N, PK3, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31dc),\
+ PINGROUP(GMI_CS3_N, PK4, GMI, RSVD1, NAND, GMI, GMI_ALT, GMI, INPUT, 0x31e0),\
+ PINGROUP(GMI_CS4_N, PK2, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31e4),\
+ PINGROUP(GMI_CS6_N, PI3, GMI, NAND, NAND_ALT, GMI, SATA, NAND, INPUT, 0x31e8),\
+ PINGROUP(GMI_CS7_N, PI6, GMI, NAND, NAND_ALT, GMI, GMI_ALT, NAND, INPUT, 0x31ec),\
+ PINGROUP(GMI_AD0, PG0, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31f0),\
+ PINGROUP(GMI_AD1, PG1, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31f4),\
+ PINGROUP(GMI_AD2, PG2, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31f8),\
+ PINGROUP(GMI_AD3, PG3, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x31fc),\
+ PINGROUP(GMI_AD4, PG4, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x3200),\
+ PINGROUP(GMI_AD5, PG5, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x3204),\
+ PINGROUP(GMI_AD6, PG6, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x3208),\
+ PINGROUP(GMI_AD7, PG7, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x320c),\
+ PINGROUP(GMI_AD8, PH0, GMI, PWM0, NAND, GMI, RSVD2, GMI, INPUT, 0x3210),\
+ PINGROUP(GMI_AD9, PH1, GMI, PWM1, NAND, GMI, RSVD2, GMI, INPUT, 0x3214),\
+ PINGROUP(GMI_AD10, PH2, GMI, PWM2, NAND, GMI, RSVD2, GMI, INPUT, 0x3218),\
+ PINGROUP(GMI_AD11, PH3, GMI, PWM3, NAND, GMI, RSVD2, GMI, INPUT, 0x321c),\
+ PINGROUP(GMI_AD12, PH4, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x3220),\
+ PINGROUP(GMI_AD13, PH5, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x3224),\
+ PINGROUP(GMI_AD14, PH6, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x3228),\
+ PINGROUP(GMI_AD15, PH7, GMI, RSVD1, NAND, GMI, RSVD2, GMI, INPUT, 0x322c),\
+ PINGROUP(GMI_A16, PJ7, GMI, UARTD, SPI4, GMI, GMI_ALT, GMI, INPUT, 0x3230),\
+ PINGROUP(GMI_A17, PB0, GMI, UARTD, SPI4, GMI, DTV, GMI, INPUT, 0x3234),\
+ PINGROUP(GMI_A18, PB1, GMI, UARTD, SPI4, GMI, DTV, GMI, INPUT, 0x3238),\
+ PINGROUP(GMI_A19, PK7, GMI, UARTD, SPI4, GMI, RSVD3, GMI, INPUT, 0x323c),\
+ PINGROUP(GMI_WR_N, PI0, GMI, RSVD1, NAND, GMI, RSVD3, GMI, INPUT, 0x3240),\
+ PINGROUP(GMI_OE_N, PI1, GMI, RSVD1, NAND, GMI, RSVD3, GMI, INPUT, 0x3244),\
+ PINGROUP(GMI_DQS, PI2, GMI, RSVD1, NAND, GMI, RSVD3, NAND, INPUT, 0x3248),\
+ PINGROUP(GMI_RST_N, PI4, GMI, NAND, NAND_ALT, GMI, RSVD3, NAND, INPUT, 0x324c),\
+ PINGROUP(GEN2_I2C_SCL, PT5, GMI, I2C2, INVALID, GMI, RSVD3, I2C2, INPUT, 0x3250),\
+ PINGROUP(GEN2_I2C_SDA, PT6, GMI, I2C2, INVALID, GMI, RSVD3, I2C2, INPUT, 0x3254),\
+ PINGROUP(SDMMC4_CLK, PCC4, SDMMC4, INVALID, NAND, GMI, SDMMC4, GMI, INPUT, 0x3258),\
+ PINGROUP(SDMMC4_CMD, PT7, SDMMC4, I2C3, NAND, GMI, SDMMC4, GMI, INPUT, 0x325c),\
+ PINGROUP(SDMMC4_DAT0, PAA0, SDMMC4, UARTE, SPI3, GMI, SDMMC4, GMI, INPUT, 0x3260),\
+ PINGROUP(SDMMC4_DAT1, PAA1, SDMMC4, UARTE, SPI3, GMI, SDMMC4, GMI, INPUT, 0x3264),\
+ PINGROUP(SDMMC4_DAT2, PAA2, SDMMC4, UARTE, SPI3, GMI, SDMMC4, GMI, INPUT, 0x3268),\
+ PINGROUP(SDMMC4_DAT3, PAA3, SDMMC4, UARTE, SPI3, GMI, SDMMC4, GMI, INPUT, 0x326c),\
+ PINGROUP(SDMMC4_DAT4, PAA4, SDMMC4, I2C3, I2S4, GMI, SDMMC4, GMI, INPUT, 0x3270),\
+ PINGROUP(SDMMC4_DAT5, PAA5, SDMMC4, VGP3, I2S4, GMI, SDMMC4, GMI, INPUT, 0x3274),\
+ PINGROUP(SDMMC4_DAT6, PAA6, SDMMC4, VGP4, I2S4, GMI, SDMMC4, GMI, INPUT, 0x3278),\
+ PINGROUP(SDMMC4_DAT7, PAA7, SDMMC4, VGP5, I2S4, GMI, SDMMC4, GMI, INPUT, 0x327c),\
PINGROUP(SDMMC4_RST_N, PCC3, SDMMC4, VGP6, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3280),\
PINGROUP(CAM_MCLK, PCC0, CAM, VI, INVALID, VI_ALT2, POPSDMMC4, RSVD, INPUT, 0x3284),\
PINGROUP(GPIO_PCC1, PCC1, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3288),\
@@ -312,82 +312,82 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
PINGROUP(GPIO_PBB6, PBB6, CAM, VGP6, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x32a4),\
PINGROUP(GPIO_PBB7, PBB7, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x32a8),\
PINGROUP(GPIO_PCC2, PCC2, CAM, I2S4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32ac),\
- PINGROUP(JTAG_RTCK, PU7, SYS, RTCK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b0),\
- PINGROUP(PWR_I2C_SCL, PZ6, SYS, I2CPWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b4),\
- PINGROUP(PWR_I2C_SDA, PZ7, SYS, I2CPWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b8),\
- PINGROUP(KB_ROW0, PR0, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32bc),\
- PINGROUP(KB_ROW1, PR1, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32c0),\
- PINGROUP(KB_ROW2, PR2, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32c4),\
- PINGROUP(KB_ROW3, PR3, SYS, KBC, INVALID, RSVD2, INVALID, RSVD, INPUT, 0x32c8),\
- PINGROUP(KB_ROW4, PR4, SYS, KBC, INVALID, TRACE, RSVD3, RSVD, INPUT, 0x32cc),\
- PINGROUP(KB_ROW5, PR5, SYS, KBC, INVALID, TRACE, OWR, RSVD, INPUT, 0x32d0),\
- PINGROUP(KB_ROW6, PR6, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32d4),\
- PINGROUP(KB_ROW7, PR7, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32d8),\
- PINGROUP(KB_ROW8, PS0, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32dc),\
- PINGROUP(KB_ROW9, PS1, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32e0),\
- PINGROUP(KB_ROW10, PS2, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32e4),\
- PINGROUP(KB_ROW11, PS3, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32e8),\
- PINGROUP(KB_ROW12, PS4, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32ec),\
- PINGROUP(KB_ROW13, PS5, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32f0),\
- PINGROUP(KB_ROW14, PS6, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32f4),\
- PINGROUP(KB_ROW15, PS7, SYS, KBC, INVALID, SDMMC2, INVALID, RSVD, INPUT, 0x32f8),\
- PINGROUP(KB_COL0, PQ0, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x32fc),\
- PINGROUP(KB_COL1, PQ1, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3300),\
- PINGROUP(KB_COL2, PQ2, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3304),\
- PINGROUP(KB_COL3, PQ3, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3308),\
- PINGROUP(KB_COL4, PQ4, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x330c),\
- PINGROUP(KB_COL5, PQ5, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3310),\
- PINGROUP(KB_COL6, PQ6, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3314),\
- PINGROUP(KB_COL7, PQ7, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3318),\
- PINGROUP(CLK_32K_OUT, PA0, SYS, BLINK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x331c),\
- PINGROUP(SYS_CLK_REQ, PZ5, SYS, SYSCLK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3320),\
+ PINGROUP(JTAG_RTCK, PU7, SYS, RTCK, RSVD1, RSVD2, RSVD3, RTCK, INPUT, 0x32b0),\
+ PINGROUP(PWR_I2C_SCL, PZ6, SYS, I2CPWR, RSVD1, RSVD2, RSVD3, I2CPWR, INPUT, 0x32b4),\
+ PINGROUP(PWR_I2C_SDA, PZ7, SYS, I2CPWR, RSVD1, RSVD2, RSVD3, I2CPWR, INPUT, 0x32b8),\
+ PINGROUP(KB_ROW0, PR0, SYS, KBC, INVALID, RSVD2, RSVD3, KBC, INPUT, 0x32bc),\
+ PINGROUP(KB_ROW1, PR1, SYS, KBC, INVALID, RSVD2, RSVD3, KBC, INPUT, 0x32c0),\
+ PINGROUP(KB_ROW2, PR2, SYS, KBC, INVALID, RSVD2, RSVD3, KBC, INPUT, 0x32c4),\
+ PINGROUP(KB_ROW3, PR3, SYS, KBC, INVALID, RSVD2, INVALID, KBC, INPUT, 0x32c8),\
+ PINGROUP(KB_ROW4, PR4, SYS, KBC, INVALID, TRACE, RSVD3, KBC, INPUT, 0x32cc),\
+ PINGROUP(KB_ROW5, PR5, SYS, KBC, INVALID, TRACE, OWR, KBC, INPUT, 0x32d0),\
+ PINGROUP(KB_ROW6, PR6, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32d4),\
+ PINGROUP(KB_ROW7, PR7, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32d8),\
+ PINGROUP(KB_ROW8, PS0, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32dc),\
+ PINGROUP(KB_ROW9, PS1, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32e0),\
+ PINGROUP(KB_ROW10, PS2, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32e4),\
+ PINGROUP(KB_ROW11, PS3, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32e8),\
+ PINGROUP(KB_ROW12, PS4, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32ec),\
+ PINGROUP(KB_ROW13, PS5, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32f0),\
+ PINGROUP(KB_ROW14, PS6, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32f4),\
+ PINGROUP(KB_ROW15, PS7, SYS, KBC, INVALID, SDMMC2, INVALID, KBC, INPUT, 0x32f8),\
+ PINGROUP(KB_COL0, PQ0, SYS, KBC, INVALID, TRACE, INVALID, KBC, INPUT, 0x32fc),\
+ PINGROUP(KB_COL1, PQ1, SYS, KBC, INVALID, TRACE, INVALID, KBC, INPUT, 0x3300),\
+ PINGROUP(KB_COL2, PQ2, SYS, KBC, INVALID, TRACE, RSVD, KBC, INPUT, 0x3304),\
+ PINGROUP(KB_COL3, PQ3, SYS, KBC, INVALID, TRACE, RSVD, KBC, INPUT, 0x3308),\
+ PINGROUP(KB_COL4, PQ4, SYS, KBC, INVALID, TRACE, RSVD, KBC, INPUT, 0x330c),\
+ PINGROUP(KB_COL5, PQ5, SYS, KBC, INVALID, TRACE, RSVD, KBC, INPUT, 0x3310),\
+ PINGROUP(KB_COL6, PQ6, SYS, KBC, INVALID, TRACE, INVALID, KBC, INPUT, 0x3314),\
+ PINGROUP(KB_COL7, PQ7, SYS, KBC, INVALID, TRACE, INVALID, KBC, INPUT, 0x3318),\
+ PINGROUP(CLK_32K_OUT, PA0, SYS, BLINK, RSVD1, RSVD2, RSVD3, BLINK, INPUT, 0x331c),\
+ PINGROUP(SYS_CLK_REQ, PZ5, SYS, SYSCLK, RSVD1, RSVD2, RSVD3, SYSCLK, INPUT, 0x3320),\
PINGROUP(CORE_PWR_REQ, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3324),\
PINGROUP(CPU_PWR_REQ, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3328),\
PINGROUP(PWR_INT_N, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x332c),\
PINGROUP(CLK_32K_IN, INVALID, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3330),\
- PINGROUP(OWR, INVALID, SYS, OWR, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3334),\
- PINGROUP(DAP1_FS, PN0, AUDIO, I2S0, HDA, GMI, SDMMC2, RSVD, INPUT, 0x3338),\
- PINGROUP(DAP1_DIN, PN1, AUDIO, I2S0, HDA, GMI, SDMMC2, RSVD, INPUT, 0x333c),\
- PINGROUP(DAP1_DOUT, PN2, AUDIO, I2S0, HDA, GMI, SDMMC2, RSVD, INPUT, 0x3340),\
- PINGROUP(DAP1_SCLK, PN3, AUDIO, I2S0, HDA, GMI, SDMMC2, RSVD, INPUT, 0x3344),\
- PINGROUP(CLK1_REQ, PEE2, AUDIO, DAP, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x3348),\
- PINGROUP(CLK1_OUT, PW4, AUDIO, EXTPERIPH1, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x334c),\
+ PINGROUP(OWR, INVALID, SYS, OWR, RSVD, RSVD, RSVD, OWR, INPUT, 0x3334),\
+ PINGROUP(DAP1_FS, PN0, AUDIO, I2S0, HDA, GMI, SDMMC2, I2S0, INPUT, 0x3338),\
+ PINGROUP(DAP1_DIN, PN1, AUDIO, I2S0, HDA, GMI, SDMMC2, I2S0, INPUT, 0x333c),\
+ PINGROUP(DAP1_DOUT, PN2, AUDIO, I2S0, HDA, GMI, SDMMC2, I2S0, INPUT, 0x3340),\
+ PINGROUP(DAP1_SCLK, PN3, AUDIO, I2S0, HDA, GMI, SDMMC2, I2S0, INPUT, 0x3344),\
+ PINGROUP(CLK1_REQ, PEE2, AUDIO, DAP, HDA, RSVD2, RSVD3, DAP, INPUT, 0x3348),\
+ PINGROUP(CLK1_OUT, PW4, AUDIO, EXTPERIPH1, RSVD1, RSVD2, RSVD3, EXTPERIPH1, INPUT, 0x334c),\
PINGROUP(SPDIF_IN, PK6, AUDIO, SPDIF, HDA, INVALID, DAPSDMMC2, RSVD, INPUT, 0x3350),\
PINGROUP(SPDIF_OUT, PK5, AUDIO, SPDIF, RSVD1, INVALID, DAPSDMMC2, RSVD, INPUT, 0x3354),\
- PINGROUP(DAP2_FS, PA2, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3358),\
- PINGROUP(DAP2_DIN, PA4, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x335c),\
- PINGROUP(DAP2_DOUT, PA5, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3360),\
- PINGROUP(DAP2_SCLK, PA3, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3364),\
- PINGROUP(SPI2_MOSI, PX0, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3368),\
- PINGROUP(SPI2_MISO, PX1, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x336c),\
- PINGROUP(SPI2_CS0_N, PX3, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3370),\
- PINGROUP(SPI2_SCK, PX2, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3374),\
- PINGROUP(SPI1_MOSI, PX4, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x3378),\
- PINGROUP(SPI1_SCK, PX5, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x337c),\
- PINGROUP(SPI1_CS0_N, PX6, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x3380),\
+ PINGROUP(DAP2_FS, PA2, AUDIO, I2S1, HDA, RSVD2, GMI, I2S1, INPUT, 0x3358),\
+ PINGROUP(DAP2_DIN, PA4, AUDIO, I2S1, HDA, RSVD2, GMI, I2S1, INPUT, 0x335c),\
+ PINGROUP(DAP2_DOUT, PA5, AUDIO, I2S1, HDA, RSVD2, GMI, I2S1, INPUT, 0x3360),\
+ PINGROUP(DAP2_SCLK, PA3, AUDIO, I2S1, HDA, RSVD2, GMI, I2S1, INPUT, 0x3364),\
+ PINGROUP(SPI2_MOSI, PX0, AUDIO, SPI6, SPI2, INVALID, GMI, SPI6, INPUT, 0x3368),\
+ PINGROUP(SPI2_MISO, PX1, AUDIO, SPI6, SPI2, INVALID, GMI, SPI6, INPUT, 0x336c),\
+ PINGROUP(SPI2_CS0_N, PX3, AUDIO, SPI6, SPI2, INVALID, GMI, SPI6, INPUT, 0x3370),\
+ PINGROUP(SPI2_SCK, PX2, AUDIO, SPI6, SPI2, INVALID, GMI, SPI6, INPUT, 0x3374),\
+ PINGROUP(SPI1_MOSI, PX4, AUDIO, SPI2, SPI1, INVALID, GMI, GMI, INPUT, 0x3378),\
+ PINGROUP(SPI1_SCK, PX5, AUDIO, SPI2, SPI1, INVALID, GMI, GMI, INPUT, 0x337c),\
+ PINGROUP(SPI1_CS0_N, PX6, AUDIO, SPI2, SPI1, INVALID, GMI, GMI, INPUT, 0x3380),\
PINGROUP(SPI1_MISO, PX7, AUDIO, INVALID, SPI1, INVALID, RSVD3, RSVD, INPUT, 0x3384),\
PINGROUP(SPI2_CS1_N, PW2, AUDIO, INVALID, SPI2, INVALID, INVALID, RSVD, INPUT, 0x3388),\
PINGROUP(SPI2_CS2_N, PW3, AUDIO, INVALID, SPI2, INVALID, INVALID, RSVD, INPUT, 0x338c),\
- PINGROUP(SDMMC3_CLK, PA6, SDMMC3, UARTA, PWM2, SDMMC3, INVALID, RSVD, INPUT, 0x3390),\
- PINGROUP(SDMMC3_CMD, PA7, SDMMC3, UARTA, PWM3, SDMMC3, INVALID, RSVD, INPUT, 0x3394),\
- PINGROUP(SDMMC3_DAT0, PB7, SDMMC3, RSVD0, RSVD1, SDMMC3, INVALID, RSVD, INPUT, 0x3398),\
- PINGROUP(SDMMC3_DAT1, PB6, SDMMC3, RSVD0, RSVD1, SDMMC3, INVALID, RSVD, INPUT, 0x339c),\
- PINGROUP(SDMMC3_DAT2, PB5, SDMMC3, RSVD0, PWM1, SDMMC3, INVALID, RSVD, INPUT, 0x33a0),\
- PINGROUP(SDMMC3_DAT3, PB4, SDMMC3, RSVD0, PWM0, SDMMC3, INVALID, RSVD, INPUT, 0x33a4),\
- PINGROUP(SDMMC3_DAT4, PD1, SDMMC3, PWM1, INVALID, SDMMC3, INVALID, RSVD, INPUT, 0x33a8),\
- PINGROUP(SDMMC3_DAT5, PD0, SDMMC3, PWM0, INVALID, SDMMC3, INVALID, RSVD, INPUT, 0x33ac),\
- PINGROUP(SDMMC3_DAT6, PD3, SDMMC3, SPDIF, INVALID, SDMMC3, INVALID, RSVD, INPUT, 0x33b0),\
- PINGROUP(SDMMC3_DAT7, PD4, SDMMC3, SPDIF, INVALID, SDMMC3, INVALID, RSVD, INPUT, 0x33b4),\
- PINGROUP(PEX_L0_PRSNT_N, PDD0, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33b8),\
- PINGROUP(PEX_L0_RST_N, PDD1, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33bc),\
- PINGROUP(PEX_L0_CLKREQ_N, PDD2, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c0),\
- PINGROUP(PEX_WAKE_N, PDD3, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c4),\
- PINGROUP(PEX_L1_PRSNT_N, PDD4, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c8),\
- PINGROUP(PEX_L1_RST_N, PDD5, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33cc),\
- PINGROUP(PEX_L1_CLKREQ_N, PDD6, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d0),\
- PINGROUP(PEX_L2_PRSNT_N, PDD7, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d4),\
- PINGROUP(PEX_L2_RST_N, PCC6, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d8),\
- PINGROUP(PEX_L2_CLKREQ_N, PCC7, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33dc),\
+ PINGROUP(SDMMC3_CLK, PA6, SDMMC3, UARTA, PWM2, SDMMC3, INVALID, SDMMC3, INPUT, 0x3390),\
+ PINGROUP(SDMMC3_CMD, PA7, SDMMC3, UARTA, PWM3, SDMMC3, INVALID, SDMMC3, INPUT, 0x3394),\
+ PINGROUP(SDMMC3_DAT0, PB7, SDMMC3, RSVD0, RSVD1, SDMMC3, INVALID, SDMMC3, INPUT, 0x3398),\
+ PINGROUP(SDMMC3_DAT1, PB6, SDMMC3, RSVD0, RSVD1, SDMMC3, INVALID, SDMMC3, INPUT, 0x339c),\
+ PINGROUP(SDMMC3_DAT2, PB5, SDMMC3, RSVD0, PWM1, SDMMC3, INVALID, SDMMC3, INPUT, 0x33a0),\
+ PINGROUP(SDMMC3_DAT3, PB4, SDMMC3, RSVD0, PWM0, SDMMC3, INVALID, SDMMC3, INPUT, 0x33a4),\
+ PINGROUP(SDMMC3_DAT4, PD1, SDMMC3, PWM1, INVALID, SDMMC3, INVALID, SDMMC3, INPUT, 0x33a8),\
+ PINGROUP(SDMMC3_DAT5, PD0, SDMMC3, PWM0, INVALID, SDMMC3, INVALID, SDMMC3, INPUT, 0x33ac),\
+ PINGROUP(SDMMC3_DAT6, PD3, SDMMC3, SPDIF, INVALID, SDMMC3, INVALID, SDMMC3, INPUT, 0x33b0),\
+ PINGROUP(SDMMC3_DAT7, PD4, SDMMC3, SPDIF, INVALID, SDMMC3, INVALID, SDMMC3, INPUT, 0x33b4),\
+ PINGROUP(PEX_L0_PRSNT_N, PDD0, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33b8),\
+ PINGROUP(PEX_L0_RST_N, PDD1, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33bc),\
+ PINGROUP(PEX_L0_CLKREQ_N, PDD2, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33c0),\
+ PINGROUP(PEX_WAKE_N, PDD3, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33c4),\
+ PINGROUP(PEX_L1_PRSNT_N, PDD4, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33c8),\
+ PINGROUP(PEX_L1_RST_N, PDD5, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33cc),\
+ PINGROUP(PEX_L1_CLKREQ_N, PDD6, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33d0),\
+ PINGROUP(PEX_L2_PRSNT_N, PDD7, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33d4),\
+ PINGROUP(PEX_L2_RST_N, PCC6, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33d8),\
+ PINGROUP(PEX_L2_CLKREQ_N, PCC7, PEXCTL, PCIE, HDA, RSVD2, RSVD3, PCIE, INPUT, 0x33dc),\
PINGROUP(HDMI_CEC, PEE3, SYS, CEC, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x33e0),\
/* END OF LIST */
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index ed6c01f..d1178a8 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -290,7 +290,10 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
#if defined(CONFIG_HAVE_ARM_SCU)
{
- u32 scu_ctrl = __raw_readl(scu_base) | 1 << 3;
+ u32 scu_ctrl = __raw_readl(scu_base) |
+ 1 << 3 | /* Enable speculative line fill*/
+ 1 << 5 | /* Enable IC standby */
+ 1 << 6; /* Enable SCU standby */
if (!(scu_ctrl & 1))
__raw_writel(scu_ctrl, scu_base);
}
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index e53effb..054eb3a 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -54,7 +54,6 @@
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
-#include <asm/suspend.h>
#include <mach/clk.h>
#include <mach/iomap.h>
@@ -98,6 +97,9 @@ struct suspend_context {
};
#ifdef CONFIG_PM_SLEEP
+#if USE_TEGRA_CPU_SUSPEND
+void *tegra_cpu_context; /* non-cacheable page for CPU context */
+#endif
phys_addr_t tegra_pgd_phys; /* pgd used by hotplug & LP2 bootup */
static pgd_t *tegra_pgd;
static DEFINE_SPINLOCK(tegra_lp2_lock);
@@ -264,6 +266,63 @@ static __init int create_suspend_pgtable(void)
return 0;
}
+/*
+ * alloc_suspend_context
+ *
+ * Allocate a non-cacheable page to hold the CPU contexts.
+ * The standard ARM CPU context save functions don't work if there's
+ * an external L2 cache controller (like a PL310) in system.
+ */
+static __init int alloc_suspend_context(void)
+{
+#if USE_TEGRA_CPU_SUSPEND
+ pgprot_t prot = __pgprot_modify(pgprot_kernel, L_PTE_MT_MASK,
+ L_PTE_MT_BUFFERABLE | L_PTE_XN);
+ struct page *ctx_page;
+ unsigned long ctx_virt = 0;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ ctx_page = alloc_pages(GFP_KERNEL, 0);
+ if (IS_ERR_OR_NULL(ctx_page))
+ goto fail;
+
+ tegra_cpu_context = vm_map_ram(&ctx_page, 1, -1, prot);
+ if (IS_ERR_OR_NULL(tegra_cpu_context))
+ goto fail;
+
+ /* Add the context page to our private pgd. */
+ ctx_virt = (unsigned long)tegra_cpu_context;
+
+ pgd = tegra_pgd + pgd_index(ctx_virt);
+ if (!pgd_present(*pgd))
+ goto fail;
+ pmd = pmd_offset(pgd, ctx_virt);
+ if (!pmd_none(*pmd))
+ goto fail;
+ pte = pte_alloc_kernel(pmd, ctx_virt);
+ if (!pte)
+ goto fail;
+
+ set_pte_ext(pte, mk_pte(ctx_page, prot), 0);
+
+ outer_clean_range(__pa(pmd), __pa(pmd + 1));
+
+ return 0;
+
+fail:
+ if (ctx_page)
+ __free_page(ctx_page);
+ if (ctx_virt)
+ vm_unmap_ram((void*)ctx_virt, 1);
+ tegra_cpu_context = NULL;
+ return -ENOMEM;
+#else
+ return 0;
+#endif
+}
+
/* ensures that sufficient time is passed for a register write to
* serialize into the 32KHz domain */
static void pmc_32kwritel(u32 val, unsigned long offs)
@@ -496,9 +555,9 @@ static void tegra_sleep_core(enum tegra_suspend_mode mode,
}
#endif
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
- cpu_suspend(v2p, tegra2_sleep_core_finish);
+ tegra2_sleep_core(v2p);
#else
- cpu_suspend(v2p, tegra3_sleep_core_finish);
+ tegra3_sleep_core(v2p);
#endif
}
@@ -509,7 +568,7 @@ static inline void tegra_sleep_cpu(unsigned long v2p)
(TEGRA_RESET_HANDLER_BASE +
tegra_cpu_reset_handler_offset));
#endif
- cpu_suspend(v2p, tegra_sleep_cpu_finish);
+ tegra_sleep_cpu_save(v2p);
}
unsigned int tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
@@ -526,8 +585,7 @@ unsigned int tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
else
mode |= TEGRA_POWER_PWRREQ_OE;
mode &= ~TEGRA_POWER_EFFECT_LP0;
- pmc_32kwritel(mode, PMC_CTRL);
- mode |= flags;
+ writel(mode, pmc + PMC_CTRL);
tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_start);
@@ -539,7 +597,7 @@ unsigned int tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
trace_cpu_cluster(POWER_CPU_CLUSTER_START);
set_power_timers(pdata->cpu_timer, 0,
clk_get_rate_all_locked(tegra_pclk));
- tegra_cluster_switch_prolog(mode);
+ tegra_cluster_switch_prolog(flags);
} else {
set_power_timers(pdata->cpu_timer, pdata->cpu_off_timer,
clk_get_rate_all_locked(tegra_pclk));
@@ -549,7 +607,7 @@ unsigned int tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
tegra_lp2_set_trigger(sleep_time);
cpu_complex_pm_enter();
- suspend_cpu_complex(mode);
+ suspend_cpu_complex(flags);
tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_prolog);
flush_cache_all();
/*
@@ -566,7 +624,7 @@ unsigned int tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
tegra_init_cache(false);
tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_switch);
- restore_cpu_complex(mode);
+ restore_cpu_complex(flags);
cpu_complex_pm_exit();
remain = tegra_lp2_timer_remain();
@@ -574,7 +632,7 @@ unsigned int tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
tegra_lp2_set_trigger(0);
if (flags & TEGRA_POWER_CLUSTER_MASK) {
- tegra_cluster_switch_epilog(mode);
+ tegra_cluster_switch_epilog(flags);
trace_cpu_cluster(POWER_CPU_CLUSTER_DONE);
}
tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_epilog);
@@ -819,6 +877,8 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
local_fiq_disable();
+ trace_cpu_suspend(CPU_SUSPEND_START);
+
cpu_pm_enter();
cpu_complex_pm_enter();
@@ -882,6 +942,8 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
if (pdata && pdata->board_resume)
pdata->board_resume(mode, TEGRA_RESUME_AFTER_CPU);
+ trace_cpu_suspend(CPU_SUSPEND_DONE);
+
local_fiq_enable();
tegra_common_resume();
@@ -1036,6 +1098,13 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
goto fail;
}
+ if (alloc_suspend_context() < 0) {
+ pr_err("%s: CPU context alloc failed -- LP0/LP1/LP2 unavailable\n",
+ __func__);
+ plat->suspend_mode = TEGRA_SUSPEND_NONE;
+ goto fail;
+ }
+
if ((tegra_get_chipid() == TEGRA_CHIPID_TEGRA3) &&
(tegra_get_revision() == TEGRA_REVISION_A01) &&
(plat->suspend_mode == TEGRA_SUSPEND_LP0)) {
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index 76d264f..4c0d8be 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -19,6 +19,7 @@
*/
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -27,6 +28,7 @@
#include <linux/io.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
+#include <trace/events/power.h>
#include <mach/clk.h>
#include <mach/iomap.h>
@@ -460,6 +462,9 @@ static int tegra_powergate_set(int id, bool new_state)
return -EBUSY;
}
+ trace_power_domain_target(powergate_partition_info[id].name, new_state,
+ smp_processor_id());
+
return 0;
}
@@ -489,6 +494,7 @@ bool tegra_powergate_is_powered(int id)
status = pmc_read(PWRGATE_STATUS) & (1 << id);
return !!status;
}
+EXPORT_SYMBOL(tegra_powergate_is_powered);
int tegra_powergate_remove_clamping(int id)
{
diff --git a/arch/arm/mach-tegra/sleep-t2.S b/arch/arm/mach-tegra/sleep-t2.S
index b205565..f703606 100644
--- a/arch/arm/mach-tegra/sleep-t2.S
+++ b/arch/arm/mach-tegra/sleep-t2.S
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/include/mach/sleep-t2.S
*
- * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2010-2011, NVIDIA Corporation.
* Copyright (c) 2011, Google, Inc.
*
* Author: Colin Cross <ccross@android.com>
@@ -179,39 +179,25 @@ ENDPROC(tegra2_cpu_is_resettable_soon)
* enters suspend in LP0 or LP1 by turning off the mmu and jumping to
* tegra2_tear_down_core in IRAM
*/
-ENTRY(tegra2_sleep_core_finish)
- bl tegra_cpu_exit_coherency
+ENTRY(tegra2_sleep_core)
+ mov r12, pc @ return here is via r12
+ b tegra_cpu_save
mov32 r1, tegra2_tear_down_core
mov32 r2, tegra2_iram_start
sub r1, r1, r2
mov32 r2, TEGRA_IRAM_CODE_AREA
add r1, r1, r2
b tegra_turn_off_mmu
-ENDPROC(tegra2_sleep_core_finish)
+ENDPROC(tegra2_sleep_core)
/*
* tegra2_sleep_wfi(unsigned long v2p)
*/
ENTRY(tegra2_sleep_wfi)
- stmfd sp!, {r4 - r9, lr}
- mov r9, sp @ save sp for aborted suspend
- adr r1, BSYM(tegra_sleep_cpu_save_finish)
- bl cpu_suspend
- ldmfd sp!, {r4 - r9, pc}
-
-tegra_sleep_cpu_save_finish:
- mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency
-
- dsb
-#ifdef MULTI_CACHE
- mov32 r10, cpu_cache
- mov lr, pc
- ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
-#else
- bl __cpuc_flush_kern_all
-#endif
-
- bl tegra_cpu_exit_coherency
+ mrc p15, 0, r2, c1, c0, 1 @ save actlr before exiting coherency
+ mov r12, pc @ return here is via r12
+ b tegra_cpu_save
+ mov r11, r2
mov32 r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
mov r3, #CPU_RESETTABLE
@@ -233,7 +219,7 @@ tegra_sleep_cpu_save_finish:
* r11 contains the original actlr
*/
- mov sp, r9 @ restore SP for aborted suspend
+ mov sp, r7 @ restore SP for aborted suspend
bl tegra_pen_lock
mov32 r3, TEGRA_PMC_VIRT
@@ -243,8 +229,18 @@ tegra_sleep_cpu_save_finish:
bl tegra_pen_unlock
+#if USE_TEGRA_CPU_SUSPEND
+ /* Enable the data cache and SMP coherency */
+ mrc p15, 0, r10, c1, c0, 0
+ orr r10, r10, #CR_C
+ dsb
+ mcr p15, 0, r10, c1, c0, 0
+ isb
mcr p15, 0, r11, c1, c0, 1 @ reenable coherency
+#else
+ mcr p15, 0, r11, c1, c0, 1 @ reenable coherency
+#endif
/* Invalidate the TLBs & BTAC */
mov r1, #0
mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs
@@ -276,7 +272,8 @@ tegra_sleep_cpu_save_finish:
no_l2_sync:
#endif
- ldmfd sp!, {r4 - r9, pc}
+ pop_ctx_regs r0, r1 @ restore context registers
+ mov pc, lr
ENDPROC(tegra2_sleep_wfi)
/*
diff --git a/arch/arm/mach-tegra/sleep-t3.S b/arch/arm/mach-tegra/sleep-t3.S
index caabeb7..4417da3 100644
--- a/arch/arm/mach-tegra/sleep-t3.S
+++ b/arch/arm/mach-tegra/sleep-t3.S
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/include/mach/sleep-t3.S
*
- * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2010-2011, NVIDIA Corporation.
*
* 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
@@ -201,13 +201,14 @@ ENDPROC(tegra3_cpu_reset)
#ifdef CONFIG_PM_SLEEP
/*
- * tegra3_sleep_core_finish(unsigned long int)
+ * tegra3_sleep_core(unsigned long v2p)
*
* enters suspend in LP0 or LP1 by turning off the mmu and jumping to
* tegra3_tear_down_core in IRAM
*/
-ENTRY(tegra3_sleep_core_finish)
- bl tegra_cpu_exit_coherency
+ENTRY(tegra3_sleep_core)
+ mov r12, pc @ return here is via r12
+ b tegra_cpu_save
/* preload all the address literals that are needed for the
* CPU power-gating process, to avoid loads from SDRAM (which are
@@ -226,33 +227,22 @@ ENTRY(tegra3_sleep_core_finish)
mov32 r2, TEGRA_IRAM_CODE_AREA
add r1, r1, r2
b tegra_turn_off_mmu
-ENDPROC(tegra3_sleep_core_finish)
+ENDPROC(tegra3_sleep_core)
/*
- * tegra3_sleep_cpu_secondary_finish(unsigned long v2p)
+ * tegra3_sleep_cpu_secondary(unsigned long v2p)
*
* Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
*/
-ENTRY(tegra3_sleep_cpu_secondary_finish)
- mov r6, lr
-
- dsb
-#ifdef MULTI_CACHE
- mov32 r10, cpu_cache
- mov lr, pc
- ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
-#else
- bl __cpuc_flush_kern_all
-#endif
-
- bl tegra_cpu_exit_coherency
+ENTRY(tegra3_sleep_cpu_secondary)
+ mov r12, pc @ return here is via r12
+ b tegra_cpu_save
/* Powergate this CPU. */
mov r0, #0 @ power mode flags (!hotplug)
bl tegra3_cpu_reset
- mov r0, #1 @ never return here
- mov pc, r6
-ENDPROC(tegra3_sleep_cpu_secondary_finish)
+ b . @ should never get here
+ENDPROC(tegra3_sleep_cpu_secondary)
/*
* tegra3_tear_down_cpu
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index 18b8799..973c867 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -131,13 +131,225 @@ ENDPROC(tegra_cpu_exit_coherency)
#ifdef CONFIG_PM_SLEEP
/*
- * tegra_sleep_cpu_finish(unsigned long int)
+ * Restore CPU state for a suspend
+ *
+ * NOTE: This is a copy of cpu_resume in arch/arm/sleep.S that has been
+ * modified to work with an L2 cache.
+ */
+ .align L1_CACHE_SHIFT
+ENTRY(tegra_cpu_resume_phys)
+#if USE_TEGRA_CPU_SUSPEND
+#ifdef CONFIG_SMP
+ adr r0, tegra_phys_sleep_sp
+ ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
+ ALT_UP(mov r1, #0)
+ and r1, r1, #15
+ ldr r0, [r0, r1, lsl #2] @ stack phys addr
+#else
+ ldr r0, tegra_phys_sleep_sp @ stack phys addr
+#endif
+ setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off
+ @ load v:p, stack, resume fn
+ ARM( ldmia r0!, {r1, sp, pc} )
+THUMB( ldmia r0!, {r1, r2, r3} )
+THUMB( mov sp, r2 )
+THUMB( bx r3 )
+#else
+ /* Use the standard cpu_resume. */
+ b cpu_resume
+#endif
+ENDPROC(tegra_cpu_resume_phys)
+
+#if USE_TEGRA_CPU_SUSPEND
+tegra_phys_sleep_sp:
+ .rept 4
+ .long 0 @ preserve stack phys ptr here
+ .endr
+#endif
+
+/*
+ * tegra_cpu_suspend
+ *
+ * Save CPU suspend state
+ * NOTE: This is a copy of cpu_suspend in arch/arm/sleep.S that has been
+ * modified to work with an L2 cache.
+ *
+ * Input:
+ * r1 = v:p offset
+ * lr = return to the caller of this function
+ * Output:
+ * sp is decremented to allocate space for CPU state on stack
+ * r0-r3,r8,r9,ip,lr corrupted
+ */
+ .align L1_CACHE_SHIFT
+ENTRY(tegra_cpu_suspend)
+ mov r9, lr
+ adr lr, tegra_cpu_resume
+#if USE_TEGRA_CPU_SUSPEND
+ stmfd sp!, {r4 - r11, lr}
+#ifdef MULTI_CPU
+ mov32 r10, processor
+ ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+#else
+ mov32 r5, cpu_suspend_size
+ mov32 ip, cpu_do_resume
+#endif
+ mov r6, sp @ current virtual SP
+ sub sp, sp, r5 @ allocate CPU state on stack
+ mov r0, sp @ save pointer to CPU save block
+ add ip, ip, r1 @ convert resume fn to phys
+ stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn
+
+#ifdef MULTI_CPU
+ mov lr, pc
+ ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+ bl cpu_do_suspend
+#endif
+ dsb
+
+ /* Disable the data cache */
+ mrc p15, 0, r10, c1, c0, 0
+ bic r10, r10, #CR_C
+ dsb
+ mcr p15, 0, r10, c1, c0, 0
+ isb
+
+ /* Flush data cache */
+#ifdef MULTI_CACHE
+ mov32 r10, cpu_cache
+ mov lr, pc
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ bl __cpuc_flush_kern_all
+#endif
+#ifdef CONFIG_CACHE_L2X0
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ cpu_id r2
+ cmp r2, #0
+ bne no_l2_sync
+#endif
+ /* Issue a PL310 cache sync operation */
+ dsb
+ mov32 r2, TEGRA_PL310_VIRT
+ movw r1, 0x730 @ cache sync
+ add r2, r2, r1
+ mov r1, #0
+ str r1, [r2]
+#endif
+
+no_l2_sync:
+ /* Invalidate the TLBs & BTAC */
+ mov r1, #0
+ mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs
+ mcr p15, 0, r1, c7, c1, 6 @ invalidate shared BTAC
+ dsb
+ isb
+
+ /* Turn off SMP coherency */
+ exit_smp r1, r2
+
+ /* Convert SP from virtual to physical address. */
+ movw r1, #0xFFF
+ bic r2, sp, r1 @ VA & 0xFFFFF000
+ mcr p15, 0, r2, c7, c8, 0 @ V2PPRPC
+ mrc p15, 0, r2, c7, c4, 0 @ PAR
+ bic r2, r2, r1 @ PA & 0xFFFFF000
+ and r0, sp, r1 @ VA & 0x00000FFF
+ orr r2, r0, r2 @ (PA & 0xFFFFF000) | (VA & 0x00000FFF)
+
+ mov32 r3, tegra_phys_sleep_sp @ per-CPU phys SP save area
+
+#ifdef CONFIG_SMP
+ ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
+ ALT_UP(mov lr, #0)
+ and lr, lr, #15
+#else
+ mov lr, #0
+#endif
+
+ /* Save the normal PRRR value */
+ mrc p15, 0, r0, c10, c2, 0 @ PRRR
+
+ /* Override all remappings to strongly ordered */
+ mov r1, #0
+ mcr p15, 0, r1, c10, c2, 0 @ PRRR
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate local TLBs
+ dsb
+ isb
+
+ /* Save the physical stack pointer */
+ str r2, [r3, lr, lsl #2] @ save phys SP
+
+ /* Restore the regular remappings */
+ mcr p15, 0, r0, c10, c2, 0 @ PRRR
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate local TLBs
+ dsb
+ isb
+#else
+ /* Use the standard cpu_suspend. */
+ adr r3, BSYM(tegra_finish_suspend)
+ b __cpu_suspend
+
+tegra_finish_suspend:
+ /* Turn off SMP coherency */
+ exit_smp r1, r6
+#endif
+ mov pc, r9
+ENDPROC(tegra_cpu_suspend)
+
+/*
+ * tegra_cpu_save
+ *
+ * Input:
+ * r0 = v:p offset
+ * r12 = return to the caller of this function
+ * Output:
+ * r0 = v:p offset
+ * r7 = SP after saving the registers but before cpu_suspend, suitable
+ * for restoring an aborted suspend
+ * sp = SP after tegra_cpu_suspend (the 'real' SP)
+ * Saves r4-r11 on the stack
+ * Corrupts r1, r3-r11
+ */
+
+ENTRY(tegra_cpu_save)
+ push_ctx_regs r1 @ save context registers
+
+ mov r7, sp @ SP after reg save, before suspend
+
+#if USE_TEGRA_CPU_SUSPEND
+ cpu_id r4
+ mov32 r5, tegra_cpu_context @ address of non-cacheable context page
+ ldr r5, [r5] @ non-cacheable context save area
+ mov r6, #0x400 @ size of one CPU context stack area
+ add r4, r4, #1
+ smlabb sp, r6, r4, r5 @ context area for this CPU
+ push_stack_token r4 @ debug check word
+ stmfd sp!, {r7} @ save the real stack pointer
+ push_stack_token r4 @ debug check word
+#endif
+
+ mov r4, r12
+ mov r8, r0
+ mov r11, r2
+ mov r1, r0
+ bl tegra_cpu_suspend
+ mov r0, r8
+ mov r2, r11
+ mov pc, r4
+ENDPROC(tegra_cpu_save)
+
+/*
+ * tegra_sleep_cpu_save(unsigned long v2p)
*
* enters suspend in LP2 by turning off the mmu and jumping to
* tegra?_tear_down_cpu
*/
-ENTRY(tegra_sleep_cpu_finish)
- bl tegra_cpu_exit_coherency
+ENTRY(tegra_sleep_cpu_save)
+ mov r12, pc @ return here is via r12
+ b tegra_cpu_save
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
mov32 r1, tegra2_tear_down_cpu
@@ -146,7 +358,35 @@ ENTRY(tegra_sleep_cpu_finish)
#endif
add r1, r1, r0
b tegra_turn_off_mmu
-ENDPROC(tegra_sleep_cpu_finish)
+ENDPROC(tegra_sleep_cpu_save)
+
+/*
+ * tegra_cpu_resume
+ *
+ * reloads the volatile CPU state from the context area
+ * initializes the processor mode stacks
+ * the mmu should be on and the CPU should be coherent before this is called
+ */
+ .align L1_CACHE_SHIFT
+tegra_cpu_resume:
+ mov r0, #0
+ mcr p15, 0, r0, c8, c3, 0 @ invalidate TLB
+ mcr p15, 0, r0, c7, c5, 6 @ flush BTAC
+ mcr p15, 0, r0, c7, c5, 0 @ flush instruction cache
+ dsb
+ isb
+
+#if USE_TEGRA_CPU_SUSPEND
+ pop_stack_token r4, r5 @ check stack debug token
+ ldmfd sp!, {r0} @ get the real stack pointer
+ pop_stack_token r4, r5 @ check stack debug token
+ mov sp, r0 @ switch to the real stack pointer
+#endif
+
+ bl cpu_init
+
+ pop_ctx_regs r1, r2 @ restore context registers
+ mov pc, lr
/*
* tegra_turn_off_mmu
@@ -155,27 +395,6 @@ ENDPROC(tegra_sleep_cpu_finish)
* r1 = physical address to jump to with mmu off
*/
ENTRY(tegra_turn_off_mmu)
- /*
- * change page table pointer to tegra_pgd_phys, so that IRAM
- * and MMU shut-off will be mapped virtual == physical
- */
- mrc p15, 0, r2, c2, c0, 0 @ TTB 0
- mov32 r3, ~PAGE_MASK
- and r2, r2, r3
- ldr r3, tegra_pgd_phys_address
- ldr r3, [r3]
- orr r3, r3, r2
- mov r2, #0
- mcr p15, 0, r2, c13, c0, 1 @ reserved context
- isb
- mcr p15, 0, r3, c2, c0, 0 @ TTB 0
- isb
-
- mov r2, #0
- mcr p15, 0, r2, c8, c3, 0 @ invalidate TLB
- mcr p15, 0, r2, c7, c5, 6 @ flush BTAC
- mcr p15, 0, r2, c7, c5, 0 @ flush instruction cache
-
mov32 r3, tegra_shut_off_mmu
add r3, r3, r0
mov r0, r1
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 59298f1..2557c3f 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -25,6 +25,11 @@
#include <mach/iomap.h>
+#ifdef CONFIG_CACHE_L2X0
+#define USE_TEGRA_CPU_SUSPEND 1
+#else
+#define USE_TEGRA_CPU_SUSPEND 0
+#endif
#ifndef CONFIG_TRUSTED_FOUNDATIONS
/* FIXME: The code associated with this should be removed if our change to
save the diagnostic regsiter in the CPU context is accepted. */
@@ -123,6 +128,61 @@
#endif
.endm
+.macro push_ctx_regs, tmp1
+ push_stack_token \tmp1 @ debug check word
+ stmfd sp!, {r4 - r11, lr}
+ /* Save the current TTB0 and CONTEXTID registers. */
+ mrc p15, 0, r5, c2, c0, 0 @ TTB 0
+ mrc p15, 0, r6, c13, c0, 1 @ CONTEXTID
+#if USE_TEGRA_DIAG_REG_SAVE
+ mrc p15, 0, r4, c15, c0, 1 @ read diagnostic register
+ stmfd sp!, {r4-r6}
+#else
+ stmfd sp!, {r5-r6}
+#endif
+ /* Switch to the tegra_pgd so that IRAM and the MMU shut-off code
+ will be flat mapped (VA==PA). We also do this because the common
+ ARM CPU state save/restore code doesn't support an external L2
+ cache controller. If the current PGD is left active, the common
+ ARM MMU restore may (and eventually will) damage the currently
+ running page tables by adding a temporary flat section mapping
+ that could be picked up by other CPUs from the L2 cache
+ resulting in a kernel panic. */
+ ldr r6, tegra_pgd_phys_address
+ ldr r6, [r6]
+ mov r7, #0
+ dsb
+ mcr p15, 0, r7, c13, c0, 1 @ CONTEXTID = reserved context
+ isb
+ mcr p15, 0, r6, c2, c0, 0 @ TTB 0
+ isb
+ mcr p15, 0, r7, c8, c3, 0 @ invalidate TLB
+ mcr p15, 0, r7, c7, c5, 6 @ flush BTAC
+ mcr p15, 0, r7, c7, c5, 0 @ flush instruction cache
+ dsb
+.endm
+
+.macro pop_ctx_regs, tmp1, tmp2
+#if USE_TEGRA_DIAG_REG_SAVE
+ ldmfd sp!, {r4-r6}
+ mcr p15, 0, r4, c15, c0, 1 @ write diagnostic register
+#else
+ ldmfd sp!, {r5-r6}
+#endif
+ dsb
+ mcr p15, 0, r5, c2, c0, 0 @ TTB 0
+ isb
+ mcr p15, 0, r6, c13, c0, 1 @ CONTEXTID = reserved context
+ isb
+ mov r7, #0
+ mcr p15, 0, r7, c8, c3, 0 @ invalidate TLB
+ mcr p15, 0, r7, c7, c5, 6 @ flush BTAC
+ mcr p15, 0, r7, c7, c5, 0 @ flush instruction cache
+ dsb
+ ldmfd sp!, {r4 - r11, lr}
+ pop_stack_token \tmp1, \tmp2 @ debug stack debug token
+.endm
+
#else /* !defined(__ASSEMBLY__) */
#define FLOW_CTRL_HALT_CPU(cpu) (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + \
@@ -145,9 +205,8 @@ static inline void flowctrl_writel(unsigned long val, void __iomem *addr)
void tegra_pen_lock(void);
void tegra_pen_unlock(void);
void tegra_cpu_wfi(void);
-int tegra_sleep_cpu_finish(unsigned long v2p);
+void tegra_sleep_cpu_save(unsigned long v2p);
void tegra_resume(void);
-void tegra_cpu_resume(void);
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
extern void tegra2_iram_start;
@@ -156,14 +215,14 @@ int tegra2_cpu_is_resettable_soon(void);
void tegra2_cpu_reset(int cpu);
void tegra2_cpu_set_resettable_soon(void);
void tegra2_cpu_clear_resettable(void);
-int tegra2_sleep_core_finish(unsigned long int);
+void tegra2_sleep_core(unsigned long v2p);
void tegra2_hotplug_shutdown(void);
void tegra2_sleep_wfi(unsigned long v2p);
#else
extern void tegra3_iram_start;
extern void tegra3_iram_end;
-int tegra3_sleep_core_finish(unsigned long int);
-int tegra3_sleep_cpu_secondary_finish(unsigned long int);
+void tegra3_sleep_core(unsigned long v2p);
+void tegra3_sleep_cpu_secondary(unsigned long v2p);
void tegra3_hotplug_shutdown(void);
#endif
diff --git a/arch/arm/mach-tegra/syncpt.c b/arch/arm/mach-tegra/syncpt.c
deleted file mode 100644
index 8ebab38..00000000
--- a/arch/arm/mach-tegra/syncpt.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc.
- *
- * Author:
- * Erik Gilling <konkers@google.com>
- *
- * Copyright (C) 2010, NVIDIA Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/iomap.h>
-#include <mach/irqs.h>
-
-#define HOST1X_SYNC_OFFSET 0x3000
-#define HOST1X_SYNC_SIZE 0x800
-enum {
- HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS = 0x40,
- HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE = 0x60
-};
-
-static void syncpt_thresh_mask(struct irq_data *data)
-{
- (void)data;
-}
-
-static void syncpt_thresh_unmask(struct irq_data *data)
-{
- (void)data;
-}
-
-static void syncpt_thresh_cascade(unsigned int irq, struct irq_desc *desc)
-{
- void __iomem *sync_regs = irq_desc_get_handler_data(desc);
- unsigned long reg;
- int id;
- struct irq_chip *chip = irq_desc_get_chip(desc);
-
- chained_irq_enter(chip, desc);
-
- reg = readl(sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
-
- for_each_set_bit(id, &reg, 32)
- generic_handle_irq(id + INT_SYNCPT_THRESH_BASE);
-
- chained_irq_exit(chip, desc);
-}
-
-static struct irq_chip syncpt_thresh_irq = {
- .name = "syncpt",
- .irq_mask = syncpt_thresh_mask,
- .irq_unmask = syncpt_thresh_unmask
-};
-
-static int __init syncpt_init_irq(void)
-{
- void __iomem *sync_regs;
- unsigned int i;
- int irq;
-
- sync_regs = ioremap(TEGRA_HOST1X_BASE + HOST1X_SYNC_OFFSET,
- HOST1X_SYNC_SIZE);
- BUG_ON(!sync_regs);
-
- writel(0xffffffffUL,
- sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE);
- writel(0xffffffffUL,
- sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
-
- for (i = 0; i < INT_SYNCPT_THRESH_NR; i++) {
- irq = INT_SYNCPT_THRESH_BASE + i;
- irq_set_chip_and_handler(irq, &syncpt_thresh_irq,
- handle_simple_irq);
- irq_set_chip_data(irq, sync_regs);
- set_irq_flags(irq, IRQF_VALID);
- }
- irq_set_chained_handler(INT_HOST1X_MPCORE_SYNCPT,
- syncpt_thresh_cascade);
- irq_set_handler_data(INT_HOST1X_MPCORE_SYNCPT, sync_regs);
-
- return 0;
-}
-
-core_initcall(syncpt_init_irq);
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index 126a1d5..af30cf2 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -2485,10 +2485,12 @@ struct clk tegra_list_periph_clks[] = {
PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 0x31E, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 0x31E, 600000000, mux_pllp_plld_pllc_clkm, MUX), /* scales with voltage and process_id */
PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 0x31E, 600000000, mux_pllp_plld_pllc_clkm, MUX), /* scales with voltage and process_id */
- PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */
+ PERIPH_CLK("usbd", "tegra-udc.0", NULL, 22, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */
PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */
PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */
PERIPH_CLK("dsia", "tegradc.0", "dsia", 48, 0, 0x31E, 500000000, mux_plld_out0, 0), /* scales with voltage */
+ PERIPH_CLK("dsi1-fixed", "tegradc.0", "dsi-fixed", 0, 0, 0x31E, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
+ PERIPH_CLK("dsi2-fixed", "tegradc.1", "dsi-fixed", 0, 0, 0x31E, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 0x31E, 72000000, mux_pllp_out3, 0),
PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 0x31E, 150000000, mux_clk_m, 0), /* same frequency as VI */
PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 0x31E, 150000000, mux_clk_m, PERIPH_NO_RESET),
@@ -2502,7 +2504,7 @@ struct clk tegra_list_shared_clks[] = {
SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_virtual_sclk),
SHARED_CLK("mon.sclk", "tegra-stat-mon", "sclk", &tegra_clk_virtual_sclk),
SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_virtual_sclk),
- SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_virtual_sclk),
+ SHARED_CLK("usbd.sclk", "tegra-udc.0", "sclk", &tegra_clk_virtual_sclk),
SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_virtual_sclk),
SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_virtual_sclk),
SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_virtual_sclk),
@@ -2518,7 +2520,7 @@ struct clk tegra_list_shared_clks[] = {
SHARED_CLK("3d.emc", "tegra_gr3d", "emc", &tegra_clk_emc),
SHARED_CLK("2d.emc", "tegra_gr2d", "emc", &tegra_clk_emc),
SHARED_CLK("mpe.emc", "tegra_mpe", "emc", &tegra_clk_emc),
- SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc),
+ SHARED_CLK("usbd.emc", "tegra-udc.0", "emc", &tegra_clk_emc),
SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc),
SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc),
SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc),
@@ -2897,11 +2899,170 @@ static struct syscore_ops tegra_clk_syscore_ops = {
.resume = tegra_clk_resume,
};
+#ifdef CONFIG_TEGRA_PREINIT_CLOCKS
+
+#define RST_DEVICES_L RST_DEVICES
+#define CLK_OUT_ENB_L 0x010
+#define CLK_RSTENB_L_HOST1X_BIT (1 << 28)
+#define CLK_RSTENB_L_DISP1_BIT (1 << 27)
+#define CLK_RSTENB_L_3D_BIT (1 << 24)
+#define CLK_RSTENB_L_2D_BIT (1 << 21)
+#define CLK_RSTENB_L_VI_BIT (1 << 20)
+#define CLK_RSTENB_L_EPP_BIT (1 << 19)
+
+#define RST_DEVICES_H 0x008
+#define CLK_OUT_ENB_H 0x014
+#define CLK_RSTENB_H_MPE_BIT (1 << 28)
+
+#define GCLK_SRC_SHIFT 30
+#define GCLK_SRC_MASK (0x3 << GCLK_SRC_SHIFT)
+#define GCLK_SRC_PLLM_OUT0 0
+#define GCLK_SRC_PLLC_OUT0 1
+#define GCLK_SRC_PLLP_OUT0 2
+#define GCLK_SRC_PLLA_OUT0 3
+#define GCLK_IDLE_DIV_SHIFT 8
+#define GCLK_IDLE_DIV_MASK (0xff << GCLK_IDLE_DIV_SHIFT)
+#define GCLK_DIV_SHIFT 0
+#define GCLK_DIV_MASK (0xff << GCLK_DIV_SHIFT)
+
+#define DISP1_CLK_REG 0x138
+#define DCLK_SRC_PLLP_OUT0 0
+#define DCLK_SRC_PLLD_OUT0 1
+#define DCLK_SRC_PLLC_OUT0 2
+#define DCLK_SRC_CLKM 3
+#define DISP1_CLK_SRC (DCLK_SRC_PLLC_OUT0 << GCLK_SRC_SHIFT)
+
+#define HOST1X_CLK_REG 0x180
+#define HOST1X_CLK_SRC (GCLK_SRC_PLLP_OUT0 << GCLK_SRC_SHIFT)
+#define HOST1X_CLK_IDLE_DIV (0 << GCLK_IDLE_DIV_SHIFT)
+#define HOST1X_CLK_DIV (3 << GCLK_DIV_SHIFT)
+
+#define G3D_CLK_REG 0x158
+#define G3D_CLK_SRC (GCLK_SRC_PLLC_OUT0 << GCLK_SRC_SHIFT)
+#define G3D_CLK_IDLE_DIV (0 << GCLK_IDLE_DIV_SHIFT)
+#define G3D_CLK_DIV (0xa << GCLK_DIV_SHIFT)
+
+#define G2D_CLK_REG 0x15c
+#define G2D_CLK_SRC (GCLK_SRC_PLLC_OUT0 << GCLK_SRC_SHIFT)
+#define G2D_CLK_IDLE_DIV (0 << GCLK_IDLE_DIV_SHIFT)
+#define G2D_CLK_DIV (0xa << GCLK_DIV_SHIFT)
+
+#define VI_CLK_REG 0x148
+#define VI_CLK_SRC (GCLK_SRC_PLLC_OUT0 << GCLK_SRC_SHIFT)
+#define VI_CLK_DIV (0xa << GCLK_DIV_SHIFT)
+
+#define EPP_CLK_REG 0x16c
+#define EPP_CLK_SRC (GCLK_SRC_PLLC_OUT0 << GCLK_SRC_SHIFT)
+#define EPP_CLK_DIV (0xa << GCLK_DIV_SHIFT)
+
+#define MPE_CLK_REG 0x170
+#define MPE_CLK_SRC (GCLK_SRC_PLLC_OUT0 << GCLK_SRC_SHIFT)
+#define MPE_CLK_DIV (0xa << GCLK_DIV_SHIFT)
+
+static void __init clk_setbit(u32 reg, u32 bit)
+{
+ u32 val = clk_readl(reg);
+
+ if ((val & bit) == bit)
+ return;
+ val |= bit;
+ clk_writel(val, reg);
+ udelay(2);
+}
+
+static void __init clk_clrbit(u32 reg, u32 bit)
+{
+ u32 val = clk_readl(reg);
+
+ if ((val & bit) == 0)
+ return;
+ val &= ~bit;
+ clk_writel(val, reg);
+ udelay(2);
+}
+
+static void __init clk_setbits(u32 reg, u32 bits, u32 mask)
+{
+ u32 val = clk_readl(reg);
+
+ if ((val & mask) == bits)
+ return;
+ val &= ~mask;
+ val |= bits;
+ clk_writel(val, reg);
+ udelay(2);
+}
+
+static int __init tegra_soc_preinit_clocks(void)
+{
+ /* vi: */
+ clk_setbit(RST_DEVICES_L, CLK_RSTENB_L_VI_BIT);
+ clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_L_VI_BIT);
+ clk_setbits(VI_CLK_REG, VI_CLK_SRC, GCLK_SRC_MASK);
+ clk_setbits(VI_CLK_REG, VI_CLK_DIV, GCLK_DIV_MASK);
+ clk_clrbit(RST_DEVICES_L, CLK_RSTENB_L_VI_BIT);
+
+ /* 3d: */
+ clk_setbit(RST_DEVICES_L, CLK_RSTENB_L_3D_BIT);
+ clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_L_3D_BIT);
+ clk_setbits(G3D_CLK_REG, G3D_CLK_SRC, GCLK_SRC_MASK);
+ clk_setbits(G3D_CLK_REG, G3D_CLK_IDLE_DIV, GCLK_IDLE_DIV_MASK);
+ clk_setbits(G3D_CLK_REG, G3D_CLK_DIV, GCLK_DIV_MASK);
+ clk_clrbit(RST_DEVICES_L, CLK_RSTENB_L_3D_BIT);
+
+ /* 2d: */
+ clk_setbit(RST_DEVICES_L, CLK_RSTENB_L_2D_BIT);
+ clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_L_2D_BIT);
+ clk_setbits(G2D_CLK_REG, G2D_CLK_SRC, GCLK_SRC_MASK);
+ clk_setbits(G2D_CLK_REG, G2D_CLK_IDLE_DIV, GCLK_IDLE_DIV_MASK);
+ clk_setbits(G2D_CLK_REG, G2D_CLK_DIV, GCLK_DIV_MASK);
+ clk_clrbit(RST_DEVICES_L, CLK_RSTENB_L_2D_BIT);
+
+ /* epp: */
+ clk_setbit(RST_DEVICES_L, CLK_RSTENB_L_EPP_BIT);
+ clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_L_EPP_BIT);
+ clk_setbits(EPP_CLK_REG, EPP_CLK_SRC, GCLK_SRC_MASK);
+ clk_setbits(EPP_CLK_REG, EPP_CLK_DIV, GCLK_DIV_MASK);
+ clk_clrbit(RST_DEVICES_L, CLK_RSTENB_L_EPP_BIT);
+
+ /* mpe: */
+ clk_setbit(RST_DEVICES_H, CLK_RSTENB_H_MPE_BIT);
+ clk_setbit(CLK_OUT_ENB_H, CLK_RSTENB_H_MPE_BIT);
+ clk_setbits(MPE_CLK_REG, MPE_CLK_SRC, GCLK_SRC_MASK);
+ clk_setbits(MPE_CLK_REG, MPE_CLK_DIV, GCLK_DIV_MASK);
+ clk_clrbit(RST_DEVICES_H, CLK_RSTENB_H_MPE_BIT);
+
+ /*
+ * Make sure host1x clock configuration has:
+ * HOST1X_CLK_SRC : PLLP_OUT0.
+ * HOST1X_CLK_DIVISOR: >2 to start from safe enough frequency.
+ */
+ clk_setbit(RST_DEVICES_L, CLK_RSTENB_L_HOST1X_BIT);
+ clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_L_HOST1X_BIT);
+ clk_setbits(HOST1X_CLK_REG, HOST1X_CLK_DIV, GCLK_DIV_MASK);
+ clk_setbits(HOST1X_CLK_REG, HOST1X_CLK_IDLE_DIV, GCLK_IDLE_DIV_MASK);
+ clk_setbits(HOST1X_CLK_REG, HOST1X_CLK_SRC, GCLK_SRC_MASK);
+ clk_clrbit(RST_DEVICES_L, CLK_RSTENB_L_HOST1X_BIT);
+
+ /* DISP1_CLK_SRC: DCLK_SRC_PLLP_OUT0 */
+ clk_setbit(RST_DEVICES_L, CLK_RSTENB_L_DISP1_BIT);
+ clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_L_DISP1_BIT);
+ clk_setbits(DISP1_CLK_REG, DISP1_CLK_SRC, GCLK_SRC_MASK);
+ clk_clrbit(RST_DEVICES_L, CLK_RSTENB_L_DISP1_BIT);
+
+ return 0;
+}
+#endif /* CONFIG_TEGRA_PREINIT_CLOCKS */
+
void __init tegra_soc_init_clocks(void)
{
int i;
struct clk *c;
+#ifdef CONFIG_TEGRA_PREINIT_CLOCKS
+ tegra_soc_preinit_clocks();
+#endif /* CONFIG_TEGRA_PREINIT_CLOCKS */
+
for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
tegra2_init_one_clock(tegra_ptr_clks[i]);
diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c
index 0bceeeb..2dfdb1d 100644
--- a/arch/arm/mach-tegra/tegra3_clocks.c
+++ b/arch/arm/mach-tegra/tegra3_clocks.c
@@ -830,10 +830,6 @@ static int tegra3_cpu_clk_set_rate(struct clk *c, unsigned long rate)
bool skip_to_backup =
skip && (clk_get_rate_all_locked(c) >= SKIPPER_ENGAGE_RATE);
- /* Hardware clock control is not possible on FPGA platforms.
- Report success so that upper level layers don't complain
- needlessly. */
-#ifndef CONFIG_TEGRA_FPGA_PLATFORM
if (c->dvfs) {
if (!c->dvfs->dvfs_rail)
return -ENOSYS;
@@ -912,7 +908,6 @@ out:
tegra3_super_clk_skipper_update(c->parent, 2, 1);
}
clk_disable(c->u.cpu.main);
-#endif
return ret;
}
@@ -3007,12 +3002,17 @@ static int tegra3_clk_shared_bus_update(struct clk *bus)
list_for_each_entry(c, &bus->shared_bus_list,
u.shared_bus_user.node) {
- /* Ignore requests from disabled users and from users with
- fixed bus-to-client ratio */
- if (c->u.shared_bus_user.enabled) {
+ /* Ignore requests from disabled floor and bw users, and from
+ * auto-users riding the bus. Always honor ceiling users, even
+ * if they are disabled - we do not want to keep enabled parent
+ * bus just because ceiling is set.
+ */
+ if (c->u.shared_bus_user.enabled ||
+ (c->u.shared_bus_user.mode == SHARED_CEILING)) {
switch (c->u.shared_bus_user.mode) {
case SHARED_BW:
- bw += c->u.shared_bus_user.rate;
+ if (bw < bus->max_rate)
+ bw += c->u.shared_bus_user.rate;
break;
case SHARED_CEILING:
ceiling = min(c->u.shared_bus_user.rate,
@@ -3025,6 +3025,16 @@ static int tegra3_clk_shared_bus_update(struct clk *bus)
}
}
}
+
+ if (bw) {
+ if (bus->flags & PERIPH_EMC_ENB) {
+ bw = tegra_emc_bw_efficiency ?
+ (bw / tegra_emc_bw_efficiency) : bus->max_rate;
+ bw = (bw < bus->max_rate / 100) ?
+ (bw * 100) : bus->max_rate;
+ }
+ bw = clk_round_rate_locked(bus, bw);
+ }
rate = min(max(rate, bw), ceiling);
old_rate = clk_get_rate_locked(bus);
@@ -3073,6 +3083,10 @@ static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
if (c->u.shared_bus_user.mode == SHARED_AUTO)
rate = 0;
+ /* BW users should not be rounded until aggregated */
+ if (c->u.shared_bus_user.mode == SHARED_BW)
+ return rate;
+
return clk_round_rate(c->parent, rate);
}
@@ -3958,7 +3972,7 @@ static struct clk tegra_clk_pclk = {
.reg_shift = 0,
.ops = &tegra_bus_ops,
.max_rate = 167000000,
- .min_rate = 12000000,
+ .min_rate = 40000000,
};
static struct raw_notifier_head sbus_rate_change_nh;
@@ -4275,11 +4289,13 @@ struct clk tegra_list_clks[] = {
PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 220000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8),
PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8),
- PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
+ PERIPH_CLK("usbd", "tegra-udc.0", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
PERIPH_CLK("dsia", "tegradc.0", "dsia", 48, 0, 500000000, mux_plld_out0, 0),
PERIPH_CLK_EX("dsib", "tegradc.1", "dsib", 82, 0xd0, 500000000, mux_plld_out0_plld2_out0, MUX | PLLD, &tegra_dsib_clk_ops),
+ PERIPH_CLK("dsi1-fixed", "tegradc.0", "dsi-fixed", 0, 0, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
+ PERIPH_CLK("dsi2-fixed", "tegradc.1", "dsi-fixed", 0, 0, 108000000, mux_pllp_out3, PERIPH_NO_ENB),
PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 102000000, mux_pllp_out3, 0),
PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
@@ -4297,7 +4313,7 @@ struct clk tegra_list_clks[] = {
SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
- SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
+ SHARED_CLK("usbd.sclk", "tegra-udc.0", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
@@ -4317,7 +4333,7 @@ struct clk tegra_list_clks[] = {
SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc, NULL, 0, SHARED_BW),
SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc, NULL, 0, SHARED_BW),
SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc, NULL, 0, 0),
- SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc, NULL, 0, 0),
+ SHARED_CLK("usbd.emc", "tegra-udc.0", "emc", &tegra_clk_emc, NULL, 0, 0),
SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc, NULL, 0, 0),
SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc, NULL, 0, 0),
SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc, NULL, 0, 0),
@@ -4326,7 +4342,8 @@ struct clk tegra_list_clks[] = {
SHARED_CLK("3d.emc", "tegra_gr3d", "emc", &tegra_clk_emc, NULL, 0, 0),
SHARED_CLK("2d.emc", "tegra_gr2d", "emc", &tegra_clk_emc, NULL, 0, 0),
SHARED_CLK("mpe.emc", "tegra_mpe", "emc", &tegra_clk_emc, NULL, 0, 0),
- SHARED_CLK("camera.emc", "tegra_camera", "emc", &tegra_clk_emc, NULL, 0, 0),
+ SHARED_CLK("camera.emc", "tegra_camera", "emc", &tegra_clk_emc, NULL, 0, SHARED_BW),
+ SHARED_CLK("sdmmc4.emc", "sdhci-tegra.3", "emc", &tegra_clk_emc, NULL, 0, 0),
SHARED_CLK("floor.emc", "floor.emc", NULL, &tegra_clk_emc, NULL, 0, 0),
SHARED_CLK("host1x.cbus", "tegra_host1x", "host1x", &tegra_clk_cbus, "host1x", 2, SHARED_AUTO),
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c
index 48c4384..657a6cf 100644
--- a/arch/arm/mach-tegra/tegra3_dvfs.c
+++ b/arch/arm/mach-tegra/tegra3_dvfs.c
@@ -33,10 +33,10 @@ static bool tegra_dvfs_core_disabled;
static struct dvfs *cpu_dvfs;
static const int cpu_millivolts[MAX_DVFS_FREQS] = {
- 800, 825, 850, 875, 900, 912, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237};
+ 800, 825, 850, 875, 900, 916, 950, 975, 1000, 1007, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237};
static const unsigned int cpu_cold_offs_mhz[MAX_DVFS_FREQS] = {
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50};
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50};
static const int core_millivolts[MAX_DVFS_FREQS] = {
950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350};
@@ -141,57 +141,59 @@ static struct dvfs_relationship tegra3_dvfs_relationships[] = {
}
static struct dvfs cpu_dvfs_table[] = {
- /* Cpu voltages (mV): 800, 825, 850, 875, 900, 912, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237 */
- CPU_DVFS("cpu_g", 0, 0, MHZ, 1, 1, 684, 684, 817, 817, 1026, 1102, 1149, 1187, 1225, 1282, 1300),
- CPU_DVFS("cpu_g", 0, 1, MHZ, 1, 1, 807, 807, 948, 948, 1117, 1171, 1206, 1300),
- CPU_DVFS("cpu_g", 0, 2, MHZ, 1, 1, 883, 883, 1039, 1039, 1178, 1206, 1300),
- CPU_DVFS("cpu_g", 0, 3, MHZ, 1, 1, 931, 931, 1102, 1102, 1216, 1300),
-
- CPU_DVFS("cpu_g", 1, 0, MHZ, 460, 460, 550, 550, 680, 680, 820, 970, 1040, 1080, 1150, 1200, 1280, 1300),
- CPU_DVFS("cpu_g", 1, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1300),
- CPU_DVFS("cpu_g", 1, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1300),
- CPU_DVFS("cpu_g", 1, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1300),
-
- CPU_DVFS("cpu_g", 2, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1250, 1300, 1330, 1400),
- CPU_DVFS("cpu_g", 2, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1280, 1300, 1350, 1400),
- CPU_DVFS("cpu_g", 2, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1300, 1350, 1400),
-
- CPU_DVFS("cpu_g", 3, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1250, 1300, 1330, 1400),
- CPU_DVFS("cpu_g", 3, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1280, 1300, 1350, 1400),
- CPU_DVFS("cpu_g", 3, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1300, 1350, 1400),
-
- CPU_DVFS("cpu_g", 4, 0, MHZ, 460, 460, 550, 550, 680, 680, 820, 970, 1040, 1080, 1150, 1200, 1240, 1280, 1320, 1360, 1360, 1500),
- CPU_DVFS("cpu_g", 4, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1250, 1300, 1330, 1360, 1400, 1500),
- CPU_DVFS("cpu_g", 4, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1280, 1300, 1340, 1380, 1500),
- CPU_DVFS("cpu_g", 4, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1500),
-
- CPU_DVFS("cpu_g", 5, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
- CPU_DVFS("cpu_g", 5, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
-
- CPU_DVFS("cpu_g", 6, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
- CPU_DVFS("cpu_g", 6, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
-
- CPU_DVFS("cpu_g", 7, 0, MHZ, 460, 460, 550, 550, 680, 680, 820, 970, 1040, 1080, 1150, 1200, 1280, 1300),
- CPU_DVFS("cpu_g", 7, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1300),
- CPU_DVFS("cpu_g", 7, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1300),
- CPU_DVFS("cpu_g", 7, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1300),
- CPU_DVFS("cpu_g", 7, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1300),
-
- CPU_DVFS("cpu_g", 8, 0, MHZ, 460, 460, 550, 550, 680, 680, 820, 970, 1040, 1080, 1150, 1200, 1280, 1300),
- CPU_DVFS("cpu_g", 8, 1, MHZ, 480, 480, 650, 650, 780, 780, 990, 1040, 1100, 1200, 1300),
- CPU_DVFS("cpu_g", 8, 2, MHZ, 520, 520, 700, 700, 860, 860, 1050, 1150, 1200, 1300),
- CPU_DVFS("cpu_g", 8, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1300),
- CPU_DVFS("cpu_g", 8, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1300),
-
- CPU_DVFS("cpu_g", 9, -1, MHZ, 1, 1, 1, 1, 1, 900, 900, 900, 900, 900, 900, 900, 900, 900),
- CPU_DVFS("cpu_g", 10, -1, MHZ, 1, 1, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900),
- CPU_DVFS("cpu_g", 11, -1, MHZ, 1, 1, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600),
-
- CPU_DVFS("cpu_g", 12, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
- CPU_DVFS("cpu_g", 12, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
-
- CPU_DVFS("cpu_g", 13, 3, MHZ, 550, 550, 770, 770, 910, 910, 1150, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
- CPU_DVFS("cpu_g", 13, 4, MHZ, 550, 550, 770, 770, 940, 940, 1160, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
+ /* Cpu voltages (mV): 800, 825, 850, 875, 900, 916, 950, 975, 1000, 1007, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237 */
+ CPU_DVFS("cpu_g", 0, 0, MHZ, 1, 1, 684, 684, 817, 817, 817, 1026, 1102, 1102, 1149, 1187, 1225, 1282, 1300),
+ CPU_DVFS("cpu_g", 0, 1, MHZ, 1, 1, 807, 807, 948, 948, 948, 1117, 1171, 1171, 1206, 1300),
+ CPU_DVFS("cpu_g", 0, 2, MHZ, 1, 1, 883, 883, 1039, 1039, 1039, 1178, 1206, 1206, 1300),
+ CPU_DVFS("cpu_g", 0, 3, MHZ, 1, 1, 931, 931, 1102, 1102, 1102, 1216, 1300, 1300),
+
+ CPU_DVFS("cpu_g", 1, 0, MHZ, 460, 460, 550, 550, 680, 680, 680, 820, 970, 970, 1040, 1080, 1150, 1200, 1280, 1300),
+ CPU_DVFS("cpu_g", 1, 1, MHZ, 480, 480, 650, 650, 780, 780, 780, 990, 1040, 1040, 1100, 1200, 1300),
+ CPU_DVFS("cpu_g", 1, 2, MHZ, 520, 520, 700, 700, 860, 860, 860, 1050, 1150, 1150, 1200, 1300),
+ CPU_DVFS("cpu_g", 1, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1300),
+
+ CPU_DVFS("cpu_g", 2, 1, MHZ, 480, 480, 650, 650, 780, 780, 780, 990, 1040, 1040, 1100, 1200, 1250, 1300, 1330, 1400),
+ CPU_DVFS("cpu_g", 2, 2, MHZ, 520, 520, 700, 700, 860, 860, 860, 1050, 1150, 1150, 1200, 1280, 1300, 1350, 1400),
+ CPU_DVFS("cpu_g", 2, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1280, 1300, 1350, 1400),
+
+ CPU_DVFS("cpu_g", 3, 1, MHZ, 480, 480, 650, 650, 780, 780, 780, 990, 1040, 1040, 1100, 1200, 1250, 1300, 1330, 1400),
+ CPU_DVFS("cpu_g", 3, 2, MHZ, 520, 520, 700, 700, 860, 860, 860, 1050, 1150, 1150, 1200, 1280, 1300, 1350, 1400),
+ CPU_DVFS("cpu_g", 3, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1280, 1300, 1350, 1400),
+
+ CPU_DVFS("cpu_g", 4, 0, MHZ, 460, 460, 550, 550, 680, 680, 680, 820, 970, 970, 1040, 1080, 1150, 1200, 1240, 1280, 1320, 1360, 1360, 1500),
+ CPU_DVFS("cpu_g", 4, 1, MHZ, 480, 480, 650, 650, 780, 780, 780, 990, 1040, 1040, 1100, 1200, 1250, 1300, 1330, 1360, 1400, 1500),
+ CPU_DVFS("cpu_g", 4, 2, MHZ, 520, 520, 700, 700, 860, 860, 860, 1050, 1150, 1150, 1200, 1280, 1300, 1340, 1380, 1500),
+ CPU_DVFS("cpu_g", 4, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1280, 1330, 1370, 1400, 1500),
+
+ CPU_DVFS("cpu_g", 5, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
+ CPU_DVFS("cpu_g", 5, 4, MHZ, 550, 550, 770, 770, 940, 940, 940, 1160, 1240, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
+
+ CPU_DVFS("cpu_g", 6, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
+ CPU_DVFS("cpu_g", 6, 4, MHZ, 550, 550, 770, 770, 940, 940, 940, 1160, 1240, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
+
+ CPU_DVFS("cpu_g", 7, 0, MHZ, 460, 460, 550, 550, 680, 680, 680, 820, 970, 970, 1040, 1080, 1150, 1200, 1280, 1300),
+ CPU_DVFS("cpu_g", 7, 1, MHZ, 480, 480, 650, 650, 780, 780, 780, 990, 1040, 1040, 1100, 1200, 1300),
+ CPU_DVFS("cpu_g", 7, 2, MHZ, 520, 520, 700, 700, 860, 860, 860, 1050, 1150, 1150, 1200, 1300),
+ CPU_DVFS("cpu_g", 7, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1300),
+ CPU_DVFS("cpu_g", 7, 4, MHZ, 550, 550, 770, 770, 940, 940, 940, 1160, 1300, 1300),
+
+ CPU_DVFS("cpu_g", 8, 0, MHZ, 460, 460, 550, 550, 680, 680, 680, 820, 970, 970, 1040, 1080, 1150, 1200, 1280, 1300),
+ CPU_DVFS("cpu_g", 8, 1, MHZ, 480, 480, 650, 650, 780, 780, 780, 990, 1040, 1040, 1100, 1200, 1300),
+ CPU_DVFS("cpu_g", 8, 2, MHZ, 520, 520, 700, 700, 860, 860, 860, 1050, 1150, 1150, 1200, 1300),
+ CPU_DVFS("cpu_g", 8, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1300),
+ CPU_DVFS("cpu_g", 8, 4, MHZ, 550, 550, 770, 770, 940, 940, 940, 1160, 1300, 1300),
+
+ CPU_DVFS("cpu_g", 9, -1, MHZ, 1, 1, 1, 1, 1, 1, 1, 1, 1, 900, 900, 900, 900, 900, 900, 900),
+ CPU_DVFS("cpu_g", 10, -1, MHZ, 1, 1, 1, 1, 1, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900),
+ CPU_DVFS("cpu_g", 11, -1, MHZ, 1, 1, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600),
+ CPU_DVFS("cpu_g", 14, -1, MHZ, 1, 1, 1, 1, 1, 1, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900),
+ CPU_DVFS("cpu_g", 15, -1, MHZ, 1, 1, 1, 1, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900),
+
+ CPU_DVFS("cpu_g", 12, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
+ CPU_DVFS("cpu_g", 12, 4, MHZ, 550, 550, 770, 770, 940, 940, 940, 1160, 1240, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
+
+ CPU_DVFS("cpu_g", 13, 3, MHZ, 550, 550, 770, 770, 910, 910, 910, 1150, 1230, 1230, 1280, 1330, 1370, 1400, 1470, 1500, 1500, 1540, 1540, 1700),
+ CPU_DVFS("cpu_g", 13, 4, MHZ, 550, 550, 770, 770, 940, 940, 940, 1160, 1240, 1240, 1280, 1360, 1390, 1470, 1500, 1520, 1520, 1590, 1700),
/*
* "Safe entry" to be used when no match for chip speedo, process
@@ -228,7 +230,7 @@ static struct dvfs core_dvfs_table[] = {
CORE_DVFS("sbus", 0, 1, KHZ, 1, 136000, 164000, 191000, 216000, 216000, 216000, 216000, 216000),
CORE_DVFS("sbus", 1, 1, KHZ, 51000, 205000, 205000, 227000, 227000, 267000, 267000, 267000, 267000),
CORE_DVFS("sbus", 2, 1, KHZ, 51000, 205000, 205000, 227000, 227000, 267000, 334000, 334000, 334000),
- CORE_DVFS("sbus", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 378000, 378000, 378000),
+ CORE_DVFS("sbus", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 334000, 334000, 334000),
CORE_DVFS("vi", 0, 1, KHZ, 1, 216000, 285000, 300000, 300000, 300000, 300000, 300000, 300000),
CORE_DVFS("vi", 1, 1, KHZ, 1, 216000, 267000, 300000, 371000, 409000, 409000, 409000, 409000),
@@ -275,7 +277,7 @@ static struct dvfs core_dvfs_table[] = {
CORE_DVFS("cbus", 0, 1, KHZ, 1, 228000, 275000, 332000, 380000, 416000, 416000, 416000, 416000),
CORE_DVFS("cbus", 1, 1, KHZ, 1, 228000, 275000, 332000, 380000, 416000, 416000, 416000, 416000),
CORE_DVFS("cbus", 2, 1, KHZ, 1, 247000, 304000, 352000, 400000, 437000, 484000, 520000, 600000),
- CORE_DVFS("cbus", 3, 1, KHZ, 1, 484000, 484000, 484000, 484000, 484000, 484000, 484000, 484000),
+ CORE_DVFS("cbus", 3, 1, KHZ, 1, 1, 1, 1, 1, 1, 484000, 484000, 484000),
CORE_DVFS("pll_c", -1, 1, KHZ, 533000, 667000, 667000, 800000, 800000, 1066000, 1066000, 1066000, 1200000),
@@ -783,19 +785,11 @@ static void core_cap_enable(bool enable)
{
int i;
- if (enable) {
+ if (enable)
tegra3_core_cap.refcnt++;
- if (tegra3_core_cap.refcnt == 1)
- for (i = 0; i < ARRAY_SIZE(core_cap_table); i++)
- if (core_cap_table[i].cap_clk)
- clk_enable(core_cap_table[i].cap_clk);
- } else if (tegra3_core_cap.refcnt) {
+ else if (tegra3_core_cap.refcnt)
tegra3_core_cap.refcnt--;
- if (tegra3_core_cap.refcnt == 0)
- for (i = ARRAY_SIZE(core_cap_table) - 1; i >= 0; i--)
- if (core_cap_table[i].cap_clk)
- clk_disable(core_cap_table[i].cap_clk);
- }
+
core_cap_update();
}
diff --git a/arch/arm/mach-tegra/tegra3_emc.c b/arch/arm/mach-tegra/tegra3_emc.c
index 0725980..2b19848 100644
--- a/arch/arm/mach-tegra/tegra3_emc.c
+++ b/arch/arm/mach-tegra/tegra3_emc.c
@@ -45,6 +45,8 @@ static bool emc_enable;
#endif
module_param(emc_enable, bool, 0644);
+u8 tegra_emc_bw_efficiency = 35;
+
#define EMC_MIN_RATE_DDR3 25500000
#define EMC_STATUS_UPDATE_TIMEOUT 100
#define TEGRA_EMC_TABLE_MAX_SIZE 16
@@ -350,6 +352,12 @@ static inline void disable_early_ack(u32 mc_override)
override_val |= mc_override & MC_EMEM_ARB_OVERRIDE_EACK_MASK;
}
+static inline void enable_early_ack(u32 mc_override)
+{
+ mc_writel((mc_override | MC_EMEM_ARB_OVERRIDE_EACK_MASK),
+ MC_EMEM_ARB_OVERRIDE);
+}
+
static inline bool dqs_preset(const struct tegra_emc_table *next_timing,
const struct tegra_emc_table *last_timing)
{
@@ -1163,6 +1171,24 @@ int tegra_emc_set_over_temp_state(unsigned long state)
return 0;
}
+int tegra_emc_set_eack_state(unsigned long state)
+{
+ unsigned long flags;
+ u32 mc_override;
+
+ spin_lock_irqsave(&emc_access_lock, flags);
+
+ mc_override = mc_readl(MC_EMEM_ARB_OVERRIDE);
+
+ if (state)
+ enable_early_ack(mc_override);
+ else
+ disable_early_ack(mc_override);
+
+ spin_unlock_irqrestore(&emc_access_lock, flags);
+ return 0;
+}
+
#ifdef CONFIG_DEBUG_FS
static struct dentry *emc_debugfs_root;
@@ -1222,6 +1248,43 @@ static int over_temp_state_set(void *data, u64 val)
DEFINE_SIMPLE_ATTRIBUTE(over_temp_state_fops, over_temp_state_get,
over_temp_state_set, "%llu\n");
+static int eack_state_get(void *data, u64 *val)
+{
+ unsigned long flags;
+ u32 mc_override;
+
+ spin_lock_irqsave(&emc_access_lock, flags);
+ mc_override = mc_readl(MC_EMEM_ARB_OVERRIDE);
+ spin_unlock_irqrestore(&emc_access_lock, flags);
+
+ *val = (mc_override & MC_EMEM_ARB_OVERRIDE_EACK_MASK);
+ return 0;
+}
+
+static int eack_state_set(void *data, u64 val)
+{
+ tegra_emc_set_eack_state(val);
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(eack_state_fops, eack_state_get,
+ eack_state_set, "%llu\n");
+
+static int efficiency_get(void *data, u64 *val)
+{
+ *val = tegra_emc_bw_efficiency;
+ return 0;
+}
+static int efficiency_set(void *data, u64 val)
+{
+ tegra_emc_bw_efficiency = (val > 100) ? 100 : val;
+ if (emc)
+ tegra_clk_shared_bus_update(emc);
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(efficiency_fops, efficiency_get,
+ efficiency_set, "%llu\n");
+
static int __init tegra_emc_debug_init(void)
{
if (!tegra_emc_table)
@@ -1243,6 +1306,14 @@ static int __init tegra_emc_debug_init(void)
emc_debugfs_root, NULL, &over_temp_state_fops))
goto err_out;
+ if (!debugfs_create_file(
+ "eack_state", S_IRUGO | S_IWUGO, emc_debugfs_root, NULL, &eack_state_fops))
+ goto err_out;
+
+ if (!debugfs_create_file("efficiency", S_IRUGO | S_IWUSR,
+ emc_debugfs_root, NULL, &efficiency_fops))
+ goto err_out;
+
return 0;
err_out:
diff --git a/arch/arm/mach-tegra/tegra3_emc.h b/arch/arm/mach-tegra/tegra3_emc.h
index cfde92c..185d777 100644
--- a/arch/arm/mach-tegra/tegra3_emc.h
+++ b/arch/arm/mach-tegra/tegra3_emc.h
@@ -27,6 +27,8 @@
#define TEGRA_EMC_BRIDGE_RATE_MIN 300000000
#define TEGRA_EMC_BRIDGE_MVOLTS_MIN 1200
+extern u8 tegra_emc_bw_efficiency;
+
struct tegra_emc_table {
u8 rev;
unsigned long rate;
@@ -59,6 +61,7 @@ void tegra_emc_dram_type_init(struct clk *c);
int tegra_emc_get_dram_type(void);
int tegra_emc_get_dram_temperature(void);
int tegra_emc_set_over_temp_state(unsigned long state);
+int tegra_emc_set_eack_state(unsigned long state);
#ifdef CONFIG_PM_SLEEP
void tegra_mc_timing_restore(void);
diff --git a/arch/arm/mach-tegra/tegra3_speedo.c b/arch/arm/mach-tegra/tegra3_speedo.c
index bd880bc..78afb28 100644
--- a/arch/arm/mach-tegra/tegra3_speedo.c
+++ b/arch/arm/mach-tegra/tegra3_speedo.c
@@ -108,8 +108,8 @@ static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
/* T30 Automotives */
/* threshold_index 12: cpu_speedo_id 9 & 10
- * 0,1,2 values correspond to speedo_id 9
- * 3,4,5 values correspond to speedo_id 10 */
+ * 0,1,2 values correspond to speedo_id 9/14
+ * 3,4,5 values correspond to speedo_id 10/15*/
{300, 311, 360, 371, 381, 415, 431},
{300, 311, 410, 431, UINT_MAX}, /* [13]: cpu_speedo_id 11: T30 auto */
@@ -462,10 +462,31 @@ void tegra_init_speedo_data(void)
soc_speedo_id = 1;
}
if (threshold_index == 12 && cpu_process_id != INVALID_PROCESS_ID) {
- if (cpu_process_id <= 2)
- cpu_speedo_id = 9;
- else if (cpu_process_id >= 3 && cpu_process_id < 6)
- cpu_speedo_id = 10;
+ if (cpu_process_id <= 2) {
+ switch(fuse_sku) {
+ case 0xb0:
+ case 0xb1:
+ cpu_speedo_id = 9;
+ break;
+ case 0x90:
+ case 0x91:
+ cpu_speedo_id = 14;
+ default:
+ break;
+ }
+ } else if (cpu_process_id >= 3 && cpu_process_id < 6) {
+ switch(fuse_sku) {
+ case 0xb0:
+ case 0xb1:
+ cpu_speedo_id = 10;
+ break;
+ case 0x90:
+ case 0x91:
+ cpu_speedo_id = 15;
+ default:
+ break;
+ }
+ }
}
pr_info("Tegra3: CPU Speedo ID %d, Soc Speedo ID %d",
cpu_speedo_id, soc_speedo_id);
@@ -510,8 +531,8 @@ int tegra_package_id(void)
* latter is resolved by the dvfs code)
*/
static const int cpu_speedo_nominal_millivolts[] =
-/* speedo_id 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 */
- { 1125, 1150, 1150, 1150, 1237, 1237, 1237, 1150, 1150, 912, 850, 850, 1237, 1237};
+/* speedo_id 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */
+ { 1125, 1150, 1150, 1150, 1237, 1237, 1237, 1150, 1150, 1007, 916, 850, 1237, 1237, 950, 900};
int tegra_cpu_speedo_mv(void)
{
diff --git a/arch/arm/mach-tegra/tegra3_thermal.c b/arch/arm/mach-tegra/tegra3_thermal.c
index 8ad7bd5..6322eb3 100644
--- a/arch/arm/mach-tegra/tegra3_thermal.c
+++ b/arch/arm/mach-tegra/tegra3_thermal.c
@@ -37,15 +37,13 @@
struct tegra_thermal {
struct tegra_thermal_device *device;
- long temp_throttle_tj;
long temp_shutdown_tj;
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
+ long temp_throttle_tj;
struct thermal_zone_device *thz;
int tc1;
int tc2;
long passive_delay;
-#else
- long temp_throttle_low_tj;
#endif
#ifdef CONFIG_TEGRA_EDP_LIMITS
int edp_thermal_zone_val;
@@ -62,10 +60,6 @@ static struct tegra_thermal thermal_state = {
#endif
};
-#ifndef CONFIG_TEGRA_THERMAL_SYSFS
-static bool throttle_enb;
-#endif
-
#ifdef CONFIG_TEGRA_EDP_LIMITS
static inline long edp2tj(struct tegra_thermal *thermal,
long edp_temp)
@@ -92,7 +86,7 @@ static inline long tj2dev(struct tegra_thermal_device *dev,
return tj_temp - dev->offset;
}
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
static int tegra_thermal_zone_bind(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdevice) {
@@ -107,7 +101,7 @@ static int tegra_thermal_zone_unbind(struct thermal_zone_device *thermal,
}
static int tegra_thermal_zone_get_temp(struct thermal_zone_device *thz,
- long *temp)
+ unsigned long *temp)
{
struct tegra_thermal *thermal = thz->devdata;
thermal->device->get_temp(thermal->device->data, temp);
@@ -130,8 +124,8 @@ static int tegra_thermal_zone_get_trip_type(
}
static int tegra_thermal_zone_get_trip_temp(struct thermal_zone_device *thz,
- int trip,
- long *temp) {
+ int trip,
+ unsigned long *temp) {
struct tegra_thermal *thermal = thz->devdata;
/* Support only Thermal Throttling (1 trip) for now */
@@ -152,20 +146,6 @@ static struct thermal_zone_device_ops tegra_thermal_zone_ops = {
};
#endif
-/* The thermal sysfs handles notifying the throttling
- * cooling device */
-#ifndef CONFIG_TEGRA_THERMAL_SYSFS
-static void tegra_therm_throttle(bool enable)
-{
- if (throttle_enb != enable) {
- mutex_lock(&thermal_state.mutex);
- tegra_throttling_enable(enable);
- throttle_enb = enable;
- mutex_unlock(&thermal_state.mutex);
- }
-}
-#endif
-
/* Make sure this function remains stateless */
void tegra_thermal_alert(void *data)
{
@@ -187,7 +167,7 @@ void tegra_thermal_alert(void *data)
mutex_lock(&thermal_state.mutex);
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
if (thermal->thz) {
if (!thermal->thz->passive)
thermal_zone_device_update(thermal->thz);
@@ -207,17 +187,11 @@ void tegra_thermal_alert(void *data)
temp_low_tj = dev2tj(thermal->device, temp_low_dev);
lo_limit_throttle_tj = temp_low_tj;
+ hi_limit_throttle_tj = thermal->temp_shutdown_tj;
+
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
hi_limit_throttle_tj = thermal->temp_throttle_tj;
-#ifndef CONFIG_TEGRA_THERMAL_SYSFS
- /* Check to see if we are currently throttling */
- if ((tegra_is_throttling() &&
- (temp_tj > thermal->temp_throttle_low_tj))
- || (temp_tj >= thermal->temp_throttle_tj)) {
- lo_limit_throttle_tj = thermal->temp_throttle_low_tj;
- hi_limit_throttle_tj = thermal->temp_shutdown_tj;
- }
-#else
if (temp_tj > thermal->temp_throttle_tj) {
lo_limit_throttle_tj = thermal->temp_throttle_tj;
hi_limit_throttle_tj = thermal->temp_shutdown_tj;
@@ -262,18 +236,6 @@ void tegra_thermal_alert(void *data)
tj2dev(thermal->device, lo_limit_tj),
tj2dev(thermal->device, hi_limit_tj));
-#ifndef CONFIG_TEGRA_THERMAL_SYSFS
- if (temp_tj >= thermal->temp_throttle_tj) {
- /* start throttling */
- if (!tegra_is_throttling())
- tegra_therm_throttle(true);
- } else if (temp_tj <= thermal->temp_throttle_low_tj) {
- /* switch off throttling */
- if (tegra_is_throttling())
- tegra_therm_throttle(false);
- }
-#endif
-
#ifdef CONFIG_TEGRA_EDP_LIMITS
/* inform edp governor */
if (thermal->edp_thermal_zone_val != temp_tj)
@@ -288,7 +250,7 @@ done:
int tegra_thermal_set_device(struct tegra_thermal_device *device)
{
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
struct thermal_zone_device *thz;
#endif
@@ -298,7 +260,7 @@ int tegra_thermal_set_device(struct tegra_thermal_device *device)
thermal_state.device = device;
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
thz = thermal_zone_device_register(thermal_state.device->name,
1, /* trips */
&thermal_state,
@@ -330,22 +292,18 @@ int tegra_thermal_set_device(struct tegra_thermal_device *device)
int __init tegra_thermal_init(struct tegra_thermal_data *data)
{
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
thermal_state.tc1 = data->tc1;
thermal_state.tc2 = data->tc2;
thermal_state.passive_delay = data->passive_delay;
-#else
- thermal_state.temp_throttle_low_tj = data->temp_throttle +
- data->temp_offset -
- data->hysteresis_throttle;
+ thermal_state.temp_throttle_tj = data->temp_throttle +
+ data->temp_offset;
#endif
mutex_init(&thermal_state.mutex);
#ifdef CONFIG_TEGRA_EDP_LIMITS
thermal_state.edp_offset = data->edp_offset;
thermal_state.hysteresis_edp = data->hysteresis_edp;
#endif
- thermal_state.temp_throttle_tj = data->temp_throttle +
- data->temp_offset;
thermal_state.temp_shutdown_tj = data->temp_shutdown +
data->temp_offset;
@@ -354,7 +312,7 @@ int __init tegra_thermal_init(struct tegra_thermal_data *data)
int tegra_thermal_exit(void)
{
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
if (thermal_state.thz)
thermal_zone_device_unregister(thermal_state.thz);
#endif
@@ -364,19 +322,11 @@ int tegra_thermal_exit(void)
#ifdef CONFIG_DEBUG_FS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
static int tegra_thermal_throttle_temp_tj_set(void *data, u64 val)
{
-#ifndef CONFIG_TEGRA_THERMAL_SYSFS
- long throttle_hysteresis = thermal_state.temp_throttle_tj -
- thermal_state.temp_throttle_low_tj;
-#endif
-
mutex_lock(&thermal_state.mutex);
thermal_state.temp_throttle_tj = val;
-#ifndef CONFIG_TEGRA_THERMAL_SYSFS
- thermal_state.temp_throttle_low_tj = thermal_state.temp_throttle_tj -
- throttle_hysteresis;
-#endif
mutex_unlock(&thermal_state.mutex);
tegra_thermal_alert(&thermal_state);
@@ -394,6 +344,7 @@ DEFINE_SIMPLE_ATTRIBUTE(throttle_temp_tj_fops,
tegra_thermal_throttle_temp_tj_get,
tegra_thermal_throttle_temp_tj_set,
"%llu\n");
+#endif
static int tegra_thermal_shutdown_temp_tj_set(void *data, u64 val)
{
@@ -447,7 +398,7 @@ DEFINE_SIMPLE_ATTRIBUTE(temp_tj_fops,
NULL,
"%llu\n");
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
static int tegra_thermal_tc1_set(void *data, u64 val)
{
thermal_state.thz->tc1 = val;
@@ -507,10 +458,6 @@ static int __init tegra_thermal_debug_init(void)
{
thermal_debugfs_root = debugfs_create_dir("tegra_thermal", 0);
- if (!debugfs_create_file("throttle_temp_tj", 0644, thermal_debugfs_root,
- NULL, &throttle_temp_tj_fops))
- goto err_out;
-
if (!debugfs_create_file("shutdown_temp_tj", 0644, thermal_debugfs_root,
NULL, &shutdown_temp_tj_fops))
goto err_out;
@@ -519,7 +466,11 @@ static int __init tegra_thermal_debug_init(void)
NULL, &temp_tj_fops))
goto err_out;
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
+#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
+ if (!debugfs_create_file("throttle_temp_tj", 0644, thermal_debugfs_root,
+ NULL, &throttle_temp_tj_fops))
+ goto err_out;
+
if (!debugfs_create_file("tc1", 0644, thermal_debugfs_root,
NULL, &tc1_fops))
goto err_out;
diff --git a/arch/arm/mach-tegra/tegra3_throttle.c b/arch/arm/mach-tegra/tegra3_throttle.c
index f927be7..9e8d32f 100644
--- a/arch/arm/mach-tegra/tegra3_throttle.c
+++ b/arch/arm/mach-tegra/tegra3_throttle.c
@@ -34,33 +34,26 @@
/* tegra throttling require frequencies in the table to be in ascending order */
static struct cpufreq_frequency_table *cpu_freq_table;
-static struct mutex *cpu_throttle_lock;
static struct {
unsigned int cpu_freq;
int core_cap_level;
- int ms;
} throttle_table[] = {
- { 0, 1000, 2000 }, /* placeholder for cpu floor rate */
- { 640000, 1000, 2000 },
- { 640000, 1000, 2000 },
- { 640000, 1000, 2000 },
- { 640000, 1000, 2000 },
- { 640000, 1000, 2000 },
- { 760000, 1000, 2000 },
- { 760000, 1050, 2000 },
- {1000000, 1050, 2000 },
- {1000000, 1100, 2000 },
+ { 0, 1000 }, /* placeholder for cpu floor rate */
+ { 640000, 1000 },
+ { 640000, 1000 },
+ { 640000, 1000 },
+ { 640000, 1000 },
+ { 640000, 1000 },
+ { 760000, 1000 },
+ { 760000, 1050 },
+ {1000000, 1050 },
+ {1000000, 1100 },
};
static int is_throttling;
static int throttle_index;
-static struct delayed_work throttle_work;
-static struct workqueue_struct *workqueue;
-static DEFINE_MUTEX(tegra_throttle_lock);
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
static struct thermal_cooling_device *cdev;
-#endif
static unsigned int clip_to_table(unsigned int cpu_freq)
{
@@ -74,81 +67,6 @@ static unsigned int clip_to_table(unsigned int cpu_freq)
return cpu_freq_table[i].frequency;
}
-static void tegra_throttle_work_func(struct work_struct *work)
-{
- unsigned int cpu_freq;
- int core_level;
-
- mutex_lock(cpu_throttle_lock);
- if (!is_throttling) {
- mutex_unlock(cpu_throttle_lock);
- return;
- }
-
- cpu_freq = tegra_getspeed(0);
- throttle_index -= throttle_index ? 1 : 0;
-
- core_level = throttle_table[throttle_index].core_cap_level;
- if (throttle_table[throttle_index].cpu_freq < cpu_freq)
- tegra_cpu_set_speed_cap(NULL);
-
- if (throttle_index || (throttle_table[0].cpu_freq < cpu_freq))
- queue_delayed_work(workqueue, &throttle_work,
- msecs_to_jiffies(throttle_table[throttle_index].ms));
-
- mutex_unlock(cpu_throttle_lock);
-
- tegra_dvfs_core_cap_level_set(core_level);
-}
-
-/*
- * tegra_throttling_enable
- * This function may sleep
- */
-void tegra_throttling_enable(bool enable)
-{
- mutex_lock(&tegra_throttle_lock);
- mutex_lock(cpu_throttle_lock);
-
- if (enable && !(is_throttling++)) {
- int core_level;
- unsigned int cpu_freq = tegra_getspeed(0);
- throttle_index = ARRAY_SIZE(throttle_table) - 1;
-
- core_level = throttle_table[throttle_index].core_cap_level;
- if (throttle_table[throttle_index].cpu_freq < cpu_freq)
- tegra_cpu_set_speed_cap(NULL);
-
- queue_delayed_work(workqueue, &throttle_work,
- msecs_to_jiffies(throttle_table[throttle_index].ms));
-
- mutex_unlock(cpu_throttle_lock);
-
- tegra_dvfs_core_cap_level_set(core_level);
- tegra_dvfs_core_cap_enable(true);
-
- mutex_unlock(&tegra_throttle_lock);
- return;
- }
-
- if (!enable && is_throttling) {
- if (!(--is_throttling)) {
- /* restore speed requested by governor */
- tegra_cpu_set_speed_cap(NULL);
- mutex_unlock(cpu_throttle_lock);
-
- tegra_dvfs_core_cap_enable(false);
- cancel_delayed_work_sync(&throttle_work);
- mutex_unlock(&tegra_throttle_lock);
- return;
- }
- }
-
- mutex_unlock(cpu_throttle_lock);
- mutex_unlock(&tegra_throttle_lock);
-}
-EXPORT_SYMBOL_GPL(tegra_throttling_enable);
-
unsigned int tegra_throttle_governor_speed(unsigned int requested_speed)
{
return is_throttling ?
@@ -161,8 +79,6 @@ bool tegra_is_throttling(void)
return is_throttling;
}
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
-
static int
tegra_throttle_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *max_state)
@@ -175,11 +91,9 @@ static int
tegra_throttle_get_cur_state(struct thermal_cooling_device *cdev,
unsigned long *cur_state)
{
- mutex_lock(cpu_throttle_lock);
*cur_state = is_throttling ?
(ARRAY_SIZE(throttle_table) - throttle_index) :
0;
- mutex_unlock(cpu_throttle_lock);
return 0;
}
@@ -190,7 +104,6 @@ tegra_throttle_set_cur_state(struct thermal_cooling_device *cdev,
{
int core_level;
- mutex_lock(cpu_throttle_lock);
if (cur_state == 0) {
/* restore speed requested by governor */
if (is_throttling) {
@@ -212,7 +125,6 @@ tegra_throttle_set_cur_state(struct thermal_cooling_device *cdev,
tegra_cpu_set_speed_cap(NULL);
}
- mutex_unlock(cpu_throttle_lock);
return 0;
}
@@ -222,7 +134,6 @@ struct thermal_cooling_device_ops tegra_throttle_cooling_ops = {
.get_cur_state = tegra_throttle_get_cur_state,
.set_cur_state = tegra_throttle_set_cur_state,
};
-#endif
int __init tegra_throttle_init(struct mutex *cpu_lock)
{
@@ -232,18 +143,6 @@ int __init tegra_throttle_init(struct mutex *cpu_lock)
if (IS_ERR_OR_NULL(table_data))
return -EINVAL;
- /*
- * High-priority, others flags default: not bound to a specific
- * CPU, has rescue worker task (in case of allocation deadlock,
- * etc.). Single-threaded.
- */
- workqueue = alloc_workqueue("cpu-tegra",
- WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1);
- if (!workqueue)
- return -ENOMEM;
- INIT_DELAYED_WORK(&throttle_work, tegra_throttle_work_func);
-
- cpu_throttle_lock = cpu_lock;
cpu_freq_table = table_data->freq_table;
throttle_table[0].cpu_freq =
cpu_freq_table[table_data->throttle_lowest_index].frequency;
@@ -253,7 +152,6 @@ int __init tegra_throttle_init(struct mutex *cpu_lock)
throttle_table[i].cpu_freq = clip_to_table(cpu_freq);
}
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
cdev = thermal_cooling_device_register("Throttle", NULL,
&tegra_throttle_cooling_ops);
@@ -261,44 +159,27 @@ int __init tegra_throttle_init(struct mutex *cpu_lock)
cdev = NULL;
return -ENODEV;
}
-#endif
return 0;
}
void tegra_throttle_exit(void)
{
-#ifdef CONFIG_TEGRA_THERMAL_SYSFS
if (cdev) {
thermal_cooling_device_unregister(cdev);
cdev = NULL;
}
-#endif
- destroy_workqueue(workqueue);
}
#ifdef CONFIG_DEBUG_FS
-
-static int throttle_debug_set(void *data, u64 val)
-{
- tegra_throttling_enable(val);
- return 0;
-}
-static int throttle_debug_get(void *data, u64 *val)
-{
- *val = (u64) is_throttling;
- return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(throttle_fops, throttle_debug_get, throttle_debug_set,
- "%llu\n");
static int table_show(struct seq_file *s, void *data)
{
int i;
for (i = 0; i < ARRAY_SIZE(throttle_table); i++)
- seq_printf(s, "[%d] = %7u %4d %5d\n",
+ seq_printf(s, "[%d] = %7u %4d\n",
i, throttle_table[i].cpu_freq,
- throttle_table[i].core_cap_level, throttle_table[i].ms);
+ throttle_table[i].core_cap_level);
return 0;
}
@@ -314,7 +195,6 @@ static ssize_t table_write(struct file *file,
int table_idx;
unsigned int cpu_freq;
int core_cap_level;
- int ms;
if (sizeof(buf) <= count)
return -EINVAL;
@@ -327,8 +207,8 @@ static ssize_t table_write(struct file *file,
buf[count] = '\0';
strim(buf);
- if (sscanf(buf, "[%d] = %u %d %d",
- &table_idx, &cpu_freq, &core_cap_level, &ms) != 4)
+ if (sscanf(buf, "[%d] = %u %d",
+ &table_idx, &cpu_freq, &core_cap_level) != 3)
return -1;
if ((table_idx < 0) || (table_idx >= ARRAY_SIZE(throttle_table)))
@@ -337,7 +217,6 @@ static ssize_t table_write(struct file *file,
/* round new settings before updating table */
throttle_table[table_idx].cpu_freq = clip_to_table(cpu_freq);
throttle_table[table_idx].core_cap_level = (core_cap_level / 50) * 50;
- throttle_table[table_idx].ms = jiffies_to_msecs(msecs_to_jiffies(ms));
return count;
}
@@ -353,10 +232,6 @@ static const struct file_operations table_fops = {
int __init tegra_throttle_debug_init(struct dentry *cpu_tegra_debugfs_root)
{
- if (!debugfs_create_file("throttle", 0644, cpu_tegra_debugfs_root,
- NULL, &throttle_fops))
- return -ENOMEM;
-
if (!debugfs_create_file("throttle_table", 0644, cpu_tegra_debugfs_root,
NULL, &table_fops))
return -ENOMEM;
diff --git a/arch/arm/mach-tegra/tegra_usb_modem_power.c b/arch/arm/mach-tegra/tegra_usb_modem_power.c
index db062ff..8854339 100644
--- a/arch/arm/mach-tegra/tegra_usb_modem_power.c
+++ b/arch/arm/mach-tegra/tegra_usb_modem_power.c
@@ -26,6 +26,9 @@
#include <linux/gpio.h>
#include <linux/usb.h>
#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/suspend.h>
+#include <linux/slab.h>
#include <linux/wakelock.h>
#include <mach/tegra_usb_modem_power.h>
@@ -43,10 +46,11 @@ struct tegra_usb_modem {
struct delayed_work recovery_work; /* modem recovery work */
const struct tegra_modem_operations *ops; /* modem operations */
unsigned int capability; /* modem capability */
+ int system_suspend; /* system suspend flag */
+ struct notifier_block pm_notifier; /* pm event notifier */
+ struct notifier_block usb_notifier; /* usb event notifier */
};
-static struct tegra_usb_modem tegra_mdm;
-
/* supported modems */
static const struct usb_device_id modem_list[] = {
{USB_DEVICE(0x1983, 0x0310), /* Icera 450 rev1 */
@@ -55,6 +59,9 @@ static const struct usb_device_id modem_list[] = {
{USB_DEVICE(0x1983, 0x0321), /* Icera 450 rev2 */
.driver_info = TEGRA_MODEM_AUTOSUSPEND,
},
+ {USB_DEVICE(0x1983, 0x0327), /* Icera 450 5AE */
+ .driver_info = TEGRA_MODEM_AUTOSUSPEND,
+ },
{}
};
@@ -65,11 +72,14 @@ static irqreturn_t tegra_usb_modem_wake_thread(int irq, void *data)
wake_lock_timeout(&modem->wake_lock, HZ);
mutex_lock(&modem->lock);
if (modem->udev) {
- usb_lock_device(modem->udev);
pr_info("modem wake (%u)\n", ++(modem->wake_cnt));
- if (usb_autopm_get_interface(modem->intf) == 0)
- usb_autopm_put_interface_async(modem->intf);
- usb_unlock_device(modem->udev);
+
+ if (!modem->system_suspend) {
+ usb_lock_device(modem->udev);
+ if (usb_autopm_get_interface(modem->intf) == 0)
+ usb_autopm_put_interface_async(modem->intf);
+ usb_unlock_device(modem->udev);
+ }
}
mutex_unlock(&modem->lock);
@@ -89,7 +99,8 @@ static void tegra_usb_modem_recovery(struct work_struct *ws)
mutex_unlock(&modem->lock);
}
-static void device_add_handler(struct usb_device *udev)
+static void device_add_handler(struct tegra_usb_modem *modem,
+ struct usb_device *udev)
{
const struct usb_device_descriptor *desc = &udev->descriptor;
struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
@@ -97,153 +108,222 @@ static void device_add_handler(struct usb_device *udev)
if (id) {
/* hold wakelock to ensure ril has enough time to restart */
- wake_lock_timeout(&tegra_mdm.wake_lock, HZ*10);
+ wake_lock_timeout(&modem->wake_lock, HZ * 10);
pr_info("Add device %d <%s %s>\n", udev->devnum,
udev->manufacturer, udev->product);
- mutex_lock(&tegra_mdm.lock);
- tegra_mdm.udev = udev;
- tegra_mdm.intf = intf;
- tegra_mdm.vid = desc->idVendor;
- tegra_mdm.pid = desc->idProduct;
- tegra_mdm.wake_cnt = 0;
- tegra_mdm.capability = id->driver_info;
- mutex_unlock(&tegra_mdm.lock);
+ mutex_lock(&modem->lock);
+ modem->udev = udev;
+ modem->intf = intf;
+ modem->vid = desc->idVendor;
+ modem->pid = desc->idProduct;
+ modem->wake_cnt = 0;
+ modem->capability = id->driver_info;
+ mutex_unlock(&modem->lock);
pr_info("persist_enabled: %u\n", udev->persist_enabled);
- if (tegra_mdm.capability & TEGRA_MODEM_AUTOSUSPEND) {
+#ifdef CONFIG_PM
+ if (modem->capability & TEGRA_MODEM_AUTOSUSPEND) {
+ pm_runtime_set_autosuspend_delay(&udev->dev, 2000);
usb_enable_autosuspend(udev);
pr_info("enable autosuspend for %s %s\n",
udev->manufacturer, udev->product);
}
+#endif
}
}
-static void device_remove_handler(struct usb_device *udev)
+static void device_remove_handler(struct tegra_usb_modem *modem,
+ struct usb_device *udev)
{
const struct usb_device_descriptor *desc = &udev->descriptor;
- if (desc->idVendor == tegra_mdm.vid &&
- desc->idProduct == tegra_mdm.pid) {
+ if (desc->idVendor == modem->vid &&
+ desc->idProduct == modem->pid) {
pr_info("Remove device %d <%s %s>\n", udev->devnum,
udev->manufacturer, udev->product);
- mutex_lock(&tegra_mdm.lock);
- tegra_mdm.udev = NULL;
- tegra_mdm.intf = NULL;
- tegra_mdm.vid = 0;
- mutex_unlock(&tegra_mdm.lock);
+ mutex_lock(&modem->lock);
+ modem->udev = NULL;
+ modem->intf = NULL;
+ modem->vid = 0;
+ mutex_unlock(&modem->lock);
- if (tegra_mdm.capability & TEGRA_MODEM_RECOVERY)
- queue_delayed_work(tegra_mdm.wq,
- &tegra_mdm.recovery_work, HZ * 10);
+ if (modem->capability & TEGRA_MODEM_RECOVERY)
+ queue_delayed_work(modem->wq,
+ &modem->recovery_work, HZ * 10);
}
}
-static int usb_notify(struct notifier_block *self, unsigned long action,
- void *blob)
+static int mdm_usb_notifier(struct notifier_block *notifier,
+ unsigned long usb_event,
+ void *udev)
{
- switch (action) {
+ struct tegra_usb_modem *modem =
+ container_of(notifier, struct tegra_usb_modem, usb_notifier);
+
+ switch (usb_event) {
case USB_DEVICE_ADD:
- device_add_handler(blob);
+ device_add_handler(modem, udev);
break;
case USB_DEVICE_REMOVE:
- device_remove_handler(blob);
+ device_remove_handler(modem, udev);
break;
}
-
return NOTIFY_OK;
}
-static struct notifier_block usb_nb = {
- .notifier_call = usb_notify,
-};
+static int mdm_pm_notifier(struct notifier_block *notifier,
+ unsigned long pm_event,
+ void *unused)
+{
+ struct tegra_usb_modem *modem =
+ container_of(notifier, struct tegra_usb_modem, pm_notifier);
-static int tegra_usb_modem_probe(struct platform_device *pdev)
+ mutex_lock(&modem->lock);
+ if (!modem->udev) {
+ mutex_unlock(&modem->lock);
+ return NOTIFY_DONE;
+ }
+
+ pr_info("%s: event %ld\n", __func__, pm_event);
+ switch (pm_event) {
+ case PM_SUSPEND_PREPARE:
+ if (wake_lock_active(&modem->wake_lock)) {
+ pr_warn("%s: wakelock was active, aborting suspend\n",
+ __func__);
+ return NOTIFY_STOP;
+ }
+
+ modem->system_suspend = 1;
+ mutex_unlock(&modem->lock);
+ return NOTIFY_OK;
+ case PM_POST_SUSPEND:
+ modem->system_suspend = 0;
+ mutex_unlock(&modem->lock);
+ return NOTIFY_OK;
+ }
+
+ mutex_unlock(&modem->lock);
+ return NOTIFY_DONE;
+}
+
+static int mdm_init(struct tegra_usb_modem *modem, struct platform_device *pdev)
{
struct tegra_usb_modem_power_platform_data *pdata =
pdev->dev.platform_data;
- int ret;
-
- if (!pdata) {
- dev_dbg(&pdev->dev, "platform_data not available\n");
- return -EINVAL;
- }
+ int ret = 0;
/* get modem operations from platform data */
- tegra_mdm.ops = (const struct tegra_modem_operations *)pdata->ops;
+ modem->ops = (const struct tegra_modem_operations *)pdata->ops;
- if (tegra_mdm.ops) {
+ if (modem->ops) {
/* modem init */
- if (tegra_mdm.ops->init) {
- ret = tegra_mdm.ops->init();
+ if (modem->ops->init) {
+ ret = modem->ops->init();
if (ret)
return ret;
}
/* start modem */
- if (tegra_mdm.ops->start)
- tegra_mdm.ops->start();
+ if (modem->ops->start)
+ modem->ops->start();
}
- mutex_init(&(tegra_mdm.lock));
- wake_lock_init(&(tegra_mdm.wake_lock), WAKE_LOCK_SUSPEND,
+ mutex_init(&(modem->lock));
+ wake_lock_init(&modem->wake_lock, WAKE_LOCK_SUSPEND,
"tegra_usb_mdm_lock");
- /* create work queue */
- tegra_mdm.wq = create_workqueue("tegra_usb_mdm_queue");
- INIT_DELAYED_WORK(&(tegra_mdm.recovery_work), tegra_usb_modem_recovery);
+ /* create work queue platform_driver_registe*/
+ modem->wq = create_workqueue("tegra_usb_mdm_queue");
+ INIT_DELAYED_WORK(&(modem->recovery_work), tegra_usb_modem_recovery);
/* create threaded irq for remote wakeup */
if (gpio_is_valid(pdata->wake_gpio)) {
/* get remote wakeup gpio from platform data */
- tegra_mdm.wake_gpio = pdata->wake_gpio;
+ modem->wake_gpio = pdata->wake_gpio;
- ret = gpio_request(tegra_mdm.wake_gpio, "usb_mdm_wake");
+ ret = gpio_request(modem->wake_gpio, "usb_mdm_wake");
if (ret)
return ret;
- tegra_gpio_enable(tegra_mdm.wake_gpio);
+ tegra_gpio_enable(modem->wake_gpio);
/* enable IRQ for remote wakeup */
- tegra_mdm.irq = gpio_to_irq(tegra_mdm.wake_gpio);
+ modem->irq = gpio_to_irq(modem->wake_gpio);
ret =
- request_threaded_irq(tegra_mdm.irq, NULL,
+ request_threaded_irq(modem->irq, NULL,
tegra_usb_modem_wake_thread,
pdata->flags, "tegra_usb_mdm_wake",
- &tegra_mdm);
+ modem);
if (ret < 0) {
dev_err(&pdev->dev, "%s: request_threaded_irq error\n",
__func__);
return ret;
}
- ret = enable_irq_wake(tegra_mdm.irq);
+ ret = enable_irq_wake(modem->irq);
if (ret) {
dev_err(&pdev->dev, "%s: enable_irq_wake error\n",
__func__);
- free_irq(tegra_mdm.irq, &tegra_mdm);
+ free_irq(modem->irq, modem);
return ret;
}
}
- usb_register_notify(&usb_nb);
- dev_info(&pdev->dev, "Initialized tegra_usb_modem_power\n");
+ modem->pm_notifier.notifier_call = mdm_pm_notifier;
+ modem->usb_notifier.notifier_call = mdm_usb_notifier;
- return 0;
+ usb_register_notify(&modem->usb_notifier);
+ register_pm_notifier(&modem->pm_notifier);
+
+ return ret;
+}
+
+static int tegra_usb_modem_probe(struct platform_device *pdev)
+{
+ struct tegra_usb_modem_power_platform_data *pdata =
+ pdev->dev.platform_data;
+ struct tegra_usb_modem *modem;
+ int ret = 0;
+
+ if (!pdata) {
+ dev_dbg(&pdev->dev, "platform_data not available\n");
+ return -EINVAL;
+ }
+
+ modem = kzalloc(sizeof(struct tegra_usb_modem), GFP_KERNEL);
+ if (!modem) {
+ dev_dbg(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ ret = mdm_init(modem, pdev);
+ if (ret) {
+ kfree(modem);
+ return ret;
+ }
+
+ dev_set_drvdata(&pdev->dev, modem);
+
+ return ret;
}
static int __exit tegra_usb_modem_remove(struct platform_device *pdev)
{
- usb_unregister_notify(&usb_nb);
+ struct tegra_usb_modem *modem = platform_get_drvdata(pdev);
- if (tegra_mdm.irq) {
- disable_irq_wake(tegra_mdm.irq);
- free_irq(tegra_mdm.irq, &tegra_mdm);
+ unregister_pm_notifier(&modem->pm_notifier);
+ usb_unregister_notify(&modem->usb_notifier);
+
+ if (modem->irq) {
+ disable_irq_wake(modem->irq);
+ free_irq(modem->irq, modem);
}
+ kfree(modem);
return 0;
}
@@ -251,17 +331,21 @@ static int __exit tegra_usb_modem_remove(struct platform_device *pdev)
static int tegra_usb_modem_suspend(struct platform_device *pdev,
pm_message_t state)
{
+ struct tegra_usb_modem *modem = platform_get_drvdata(pdev);
+
/* send L3 hint to modem */
- if (tegra_mdm.ops && tegra_mdm.ops->suspend)
- tegra_mdm.ops->suspend();
+ if (modem->ops && modem->ops->suspend)
+ modem->ops->suspend();
return 0;
}
static int tegra_usb_modem_resume(struct platform_device *pdev)
{
+ struct tegra_usb_modem *modem = platform_get_drvdata(pdev);
+
/* send L3->L0 hint to modem */
- if (tegra_mdm.ops && tegra_mdm.ops->resume)
- tegra_mdm.ops->resume();
+ if (modem->ops && modem->ops->resume)
+ modem->ops->resume();
return 0;
}
#endif
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index e1cfcce..8c36159 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -859,7 +859,7 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
val |= HOSTPC1_DEVLC_PHCD;
writel(val, base + HOSTPC1_DEVLC);
#endif
- if (phy->instance == 2) {
+ if (phy->hotplug) {
val = readl(base + USB_SUSP_CTRL);
val |= USB_PHY_CLK_VALID_INT_ENB;
writel(val, base + USB_SUSP_CTRL);
@@ -1667,8 +1667,11 @@ static int utmi_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup)
static int utmi_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
void __iomem *base = phy->regs;
+#else
void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+#endif
unsigned int inst = phy->instance;
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
@@ -1723,7 +1726,7 @@ static int uhsic_phy_preresume(struct tegra_usb_phy *phy, bool remote_wakeup)
return 0;
}
-static int uhsic_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
+static int usb_phy_set_tx_fill_tuning(struct tegra_usb_phy *phy, bool is_dpd)
{
unsigned long val;
void __iomem *base = phy->regs;
@@ -2401,11 +2404,7 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy, bool is_dpd)
val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
writel(val, base + HOSTPC1_DEVLC);
#endif
- val = readl(base + USB_TXFILLTUNING);
- if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) {
- val = USB_FIFO_TXFILL_THRES(0x10);
- writel(val, base + USB_TXFILLTUNING);
- }
+ usb_phy_set_tx_fill_tuning(phy, is_dpd);
val = readl(base + USB_PORTSC1);
val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
@@ -2497,7 +2496,7 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
int i;
int err;
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
- struct tegra_ulpi_config *uhsic_config;
+ struct tegra_uhsic_config *uhsic_config;
int reset_gpio, enable_gpio;
#endif
@@ -2763,11 +2762,14 @@ void tegra_usb_phy_postresume(struct tegra_usb_phy *phy, bool is_dpd)
utmi_phy_postresume,
NULL,
NULL,
- uhsic_phy_postresume,
+ NULL,
};
- if (postresume[phy->usb_phy_type])
- postresume[phy->usb_phy_type](phy, is_dpd);
+ usb_phy_set_tx_fill_tuning(phy, is_dpd);
+
+ // If Phy type is utmi, call its post resume
+ if (phy->usb_phy_type == 0)
+ utmi_phy_postresume(phy, is_dpd);
}
void tegra_ehci_pre_reset(struct tegra_usb_phy *phy, bool is_dpd)
diff --git a/arch/arm/mach-tegra/wdt-recovery.c b/arch/arm/mach-tegra/wdt-recovery.c
index 537b1c0..f5a18bb 100644
--- a/arch/arm/mach-tegra/wdt-recovery.c
+++ b/arch/arm/mach-tegra/wdt-recovery.c
@@ -30,7 +30,7 @@
#include <asm/mach/time.h>
#include <asm/localtimer.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/irqs.h>
#include <mach/iomap.h>
#include <mach/clk.h>
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 0dddb54..e6871a3 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -335,6 +335,8 @@ static void __init l2x0_unlock(__u32 cache_id)
int lockregs;
int i;
+ cache_id &= L2X0_CACHE_ID_PART_MASK;
+
if (cache_id == L2X0_CACHE_ID_PART_L310)
lockregs = 8;
else
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 88fb3d9..2e6849b 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -379,26 +379,31 @@ ENTRY(cpu_arm920_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
.globl cpu_arm920_suspend_size
-.equ cpu_arm920_suspend_size, 4 * 3
+.equ cpu_arm920_suspend_size, 4 * 4
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_arm920_do_suspend)
- stmfd sp!, {r4 - r6, lr}
+ stmfd sp!, {r4 - r7, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c1, c0, 0 @ Control register
- stmia r0, {r4 - r6}
- ldmfd sp!, {r4 - r6, pc}
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
ENDPROC(cpu_arm920_do_suspend)
ENTRY(cpu_arm920_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
- ldmia r0, {r4 - r6}
+ ldmia r0, {r4 - r7}
mcr p15, 0, r4, c13, c0, 0 @ PID
mcr p15, 0, r5, c3, c0, 0 @ Domain ID
- mcr p15, 0, r1, c2, c0, 0 @ TTB address
- mov r0, r6 @ control register
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
b cpu_resume_mmu
ENDPROC(cpu_arm920_do_resume)
#endif
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 9f8fd91..cd8f79c 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -394,26 +394,31 @@ ENTRY(cpu_arm926_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
.globl cpu_arm926_suspend_size
-.equ cpu_arm926_suspend_size, 4 * 3
+.equ cpu_arm926_suspend_size, 4 * 4
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_arm926_do_suspend)
- stmfd sp!, {r4 - r6, lr}
+ stmfd sp!, {r4 - r7, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c1, c0, 0 @ Control register
- stmia r0, {r4 - r6}
- ldmfd sp!, {r4 - r6, pc}
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
ENDPROC(cpu_arm926_do_suspend)
ENTRY(cpu_arm926_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
- ldmia r0, {r4 - r6}
+ ldmia r0, {r4 - r7}
mcr p15, 0, r4, c13, c0, 0 @ PID
mcr p15, 0, r5, c3, c0, 0 @ Domain ID
- mcr p15, 0, r1, c2, c0, 0 @ TTB address
- mov r0, r6 @ control register
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
b cpu_resume_mmu
ENDPROC(cpu_arm926_do_resume)
#endif
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 7d91545..69e7f2e 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -168,19 +168,20 @@ ENTRY(cpu_sa1100_set_pte_ext)
mov pc, lr
.globl cpu_sa1100_suspend_size
-.equ cpu_sa1100_suspend_size, 4 * 3
+.equ cpu_sa1100_suspend_size, 4*4
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_sa1100_do_suspend)
- stmfd sp!, {r4 - r6, lr}
+ stmfd sp!, {r4 - r7, lr}
mrc p15, 0, r4, c3, c0, 0 @ domain ID
- mrc p15, 0, r5, c13, c0, 0 @ PID
- mrc p15, 0, r6, c1, c0, 0 @ control reg
- stmia r0, {r4 - r6} @ store cp regs
- ldmfd sp!, {r4 - r6, pc}
+ mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c1, c0, 0 @ control reg
+ stmia r0, {r4 - r7} @ store cp regs
+ ldmfd sp!, {r4 - r7, pc}
ENDPROC(cpu_sa1100_do_suspend)
ENTRY(cpu_sa1100_do_resume)
- ldmia r0, {r4 - r6} @ load cp regs
+ ldmia r0, {r4 - r7} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs
mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache
@@ -188,9 +189,13 @@ ENTRY(cpu_sa1100_do_resume)
mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB
mcr p15, 0, r4, c3, c0, 0 @ domain ID
- mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r5, c13, c0, 0 @ PID
- mov r0, r6 @ control register
+ mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mov r0, r7 @ control register
+ mov r2, r5, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
b cpu_resume_mmu
ENDPROC(cpu_sa1100_do_resume)
#endif
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index d061d2f..a923aa0 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -128,18 +128,20 @@ ENTRY(cpu_v6_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
.globl cpu_v6_suspend_size
-.equ cpu_v6_suspend_size, 4 * 6
+.equ cpu_v6_suspend_size, 4 * 8
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_v6_do_suspend)
- stmfd sp!, {r4 - r9, lr}
+ stmfd sp!, {r4 - r11, lr}
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c2, c0, 1 @ Translation table base 1
- mrc p15, 0, r7, c1, c0, 1 @ auxiliary control register
- mrc p15, 0, r8, c1, c0, 2 @ co-processor access control
- mrc p15, 0, r9, c1, c0, 0 @ control register
- stmia r0, {r4 - r9}
- ldmfd sp!, {r4- r9, pc}
+ mrc p15, 0, r5, c13, c0, 1 @ Context ID
+ mrc p15, 0, r6, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r7, c2, c0, 0 @ Translation table base 0
+ mrc p15, 0, r8, c2, c0, 1 @ Translation table base 1
+ mrc p15, 0, r9, c1, c0, 1 @ auxiliary control register
+ mrc p15, 0, r10, c1, c0, 2 @ co-processor access control
+ mrc p15, 0, r11, c1, c0, 0 @ control register
+ stmia r0, {r4 - r11}
+ ldmfd sp!, {r4- r11, pc}
ENDPROC(cpu_v6_do_suspend)
ENTRY(cpu_v6_do_resume)
@@ -148,21 +150,25 @@ ENTRY(cpu_v6_do_resume)
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
- mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
- ldmia r0, {r4 - r9}
+ ldmia r0, {r4 - r11}
mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mcr p15, 0, r5, c3, c0, 0 @ Domain ID
- ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP)
- ALT_UP(orr r1, r1, #TTB_FLAGS_UP)
- mcr p15, 0, r1, c2, c0, 0 @ Translation table base 0
- mcr p15, 0, r6, c2, c0, 1 @ Translation table base 1
- mcr p15, 0, r7, c1, c0, 1 @ auxiliary control register
- mcr p15, 0, r8, c1, c0, 2 @ co-processor access control
+ mcr p15, 0, r5, c13, c0, 1 @ Context ID
+ mcr p15, 0, r6, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r7, c2, c0, 0 @ Translation table base 0
+ mcr p15, 0, r8, c2, c0, 1 @ Translation table base 1
+ mcr p15, 0, r9, c1, c0, 1 @ auxiliary control register
+ mcr p15, 0, r10, c1, c0, 2 @ co-processor access control
mcr p15, 0, ip, c2, c0, 2 @ TTB control register
mcr p15, 0, ip, c7, c5, 4 @ ISB
- mov r0, r9 @ control register
+ mov r0, r11 @ control register
+ mov r2, r7, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
b cpu_resume_mmu
ENDPROC(cpu_v6_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
#endif
string cpu_v6_name, "ARMv6-compatible processor"
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index bd0f3a1..a502958 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -260,17 +260,19 @@ ENDPROC(cpu_v7_set_pte_ext)
.equ cpu_v7_suspend_size, (4 * 10) + cpu_v7_debug_suspend_size
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_v7_do_suspend)
- stmfd sp!, {r0, r3 - r10, lr}
+ stmfd sp!, {r0, r3 - r11, lr}
mrc p15, 0, r3, c15, c0, 1 @ diag
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID
- stmia r0!, {r3 - r5}
+ mrc p15, 0, r5, c13, c0, 1 @ Context ID
+ mrc p15, 0, r6, c13, c0, 3 @ User r/o thread ID
+ stmia r0!, {r3 - r6}
mrc p15, 0, r6, c3, c0, 0 @ Domain ID
- mrc p15, 0, r7, c2, c0, 1 @ TTB 1
- mrc p15, 0, r8, c1, c0, 0 @ Control register
- mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
- mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
- stmia r0!, {r6 - r10}
+ mrc p15, 0, r7, c2, c0, 0 @ TTB 0
+ mrc p15, 0, r8, c2, c0, 1 @ TTB 1
+ mrc p15, 0, r9, c1, c0, 0 @ Control register
+ mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control
+ stmia r0!, {r6 - r11}
#ifdef CONFIG_ARM_SAVE_DEBUG_CONTEXT
/* Save CP14 debug controller context */
@@ -295,7 +297,7 @@ ENTRY(cpu_v7_do_suspend)
mrc p14, 0, r8, c0, c0, 0 @ read IDR
mov r3, r8, lsr #24
- and r3, r3, #0xf @ r3 has the number of brkpt
+ and r3, r3, #0xf @ r3 has the number of brkpt
rsb r3, r3, #0xf
/* r3 = (15 - #of brkpt) ;
@@ -322,7 +324,7 @@ ENTRY(cpu_v7_do_suspend)
save_brkpt c1
save_brkpt c0
- mov r3, r8, lsr #28 @ r3 has the number of wpt
+ mov r3, r8, lsr #28 @ r3 has the number of wpt
rsb r3, r3, #0xf
/* r3 = (15 - #of wpt) ;
@@ -349,31 +351,29 @@ ENTRY(cpu_v7_do_suspend)
save_wpt c1
save_wpt c0
#endif
- ldmfd sp!, {r0, r3 - r10, pc}
+ ldmfd sp!, {r0, r3 - r11, pc}
ENDPROC(cpu_v7_do_suspend)
ENTRY(cpu_v7_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
- mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID
- ldmia r0!, {r3 - r5}
+ ldmia r0!, {r3 - r6}
#ifndef CONFIG_TRUSTED_FOUNDATIONS
mcr p15, 0, r3, c15, c0, 1 @ diag
#endif
mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID
- ldmia r0!, {r6 - r10}
+ mcr p15, 0, r5, c13, c0, 1 @ Context ID
+ mcr p15, 0, r6, c13, c0, 3 @ User r/o thread ID
+ ldmia r0!, {r6 - r11}
mcr p15, 0, r6, c3, c0, 0 @ Domain ID
- ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP)
- ALT_UP(orr r1, r1, #TTB_FLAGS_UP)
- mcr p15, 0, r1, c2, c0, 0 @ TTB 0
- mcr p15, 0, r7, c2, c0, 1 @ TTB 1
+ mcr p15, 0, r7, c2, c0, 0 @ TTB 0
+ mcr p15, 0, r8, c2, c0, 1 @ TTB 1
mcr p15, 0, ip, c2, c0, 2 @ TTB control register
mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register
- teq r4, r9 @ Is it already set?
- mcrne p15, 0, r9, c1, c0, 1 @ No, so write it
- mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ teq r4, r10 @ Is it already set?
+ mcrne p15, 0, r10, c1, c0, 1 @ No, so write it
+ mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control
ldr r4, =PRRR @ PRRR
ldr r5, =NMRR @ NMRR
mcr p15, 0, r4, c10, c2, 0 @ write PRRR
@@ -382,6 +382,7 @@ ENTRY(cpu_v7_do_resume)
#ifdef CONFIG_ARM_SAVE_DEBUG_CONTEXT
/* Restore CP14 debug controller context */
+
ldmia r0!, {r2 - r5}
mcr p14, 0, r3, c0, c6, 0 @ DBGWFAR
mcr p14, 0, r4, c0, c7, 0 @ DBGVCR
@@ -399,15 +400,14 @@ ENTRY(cpu_v7_do_resume)
ldrne r4, [r0], #4
mcrne p14, 0, r4, c0, c0, 2 @ DBGDTRRXext
- mrc p14, 0, r6, c0, c0, 0 @ read IDR
- mov r3, r6, lsr #24
- and r3, r3, #0xf @ r3 has the number of brkpt
+ mrc p14, 0, r8, c0, c0, 0 @ read IDR
+ mov r3, r8, lsr #24
+ and r3, r3, #0xf @ r3 has the number of brkpt
rsb r3, r3, #0xf
- /*
- * r3 = (15 - # of wpt) ;
- * switch offset = r3*12 - 4 = (r3*3 - 1)<<2
- */
+ /* r3 = (15 - #of wpt) ;
+ switch offset = r3*12 - 4 = (r3*3 - 1)<<2
+ */
add r3, r3, r3, lsl #1
sub r3, r3, #1
add pc, pc, r3, lsl #2
@@ -429,7 +429,7 @@ ENTRY(cpu_v7_do_resume)
restore_brkpt c1
restore_brkpt c0
- mov r3, r6, lsr #28 @ r3 has the number of wpt
+ mov r3, r8, lsr #28 @ r3 has the number of wpt
rsb r3, r3, #0xf
/* r3 = (15 - #of wpt) ;
@@ -462,9 +462,15 @@ start_restore_wpt:
isb
#endif
dsb
- mov r0, r8 @ Control Register
+ mov r0, r9 @ control register
+ mov r2, r7, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
b cpu_resume_mmu
ENDPROC(cpu_v7_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
#endif
__CPUINIT
@@ -545,6 +551,12 @@ __v7_setup:
mrcge p15, 0, r10, c15, c0, 0 @ read power control register
orrge r10, r10, #1 @ enable dynamic clock gating
mcrge p15, 0, r10, c15, c0, 0 @ write power control register
+#ifdef CONFIG_ARM_ERRATA_716044
+ cmp r6, #0x12 @ present in r1p0 - r1p2
+ mrcle p15, 0, r10, c1, c0, 0
+ orrle r10, r10, #(1 << 14) @ set SCTLR.RR
+ mcrle p15, 0, r10, c1, c0, 0
+#endif
#ifdef CONFIG_ARM_ERRATA_720791
teq r5, #0x00100000 @ only present in r1p*
mrceq p15, 0, r10, c15, c0, 2 @ read "chicken power ctrl" reg
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 5ae0db4..1a2021c 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -406,23 +406,24 @@ ENTRY(cpu_xsc3_set_pte_ext)
.align
.globl cpu_xsc3_suspend_size
-.equ cpu_xsc3_suspend_size, 4 * 6
+.equ cpu_xsc3_suspend_size, 4 * 7
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_xsc3_do_suspend)
- stmfd sp!, {r4 - r9, lr}
+ stmfd sp!, {r4 - r10, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
mrc p15, 0, r5, c15, c1, 0 @ CP access reg
mrc p15, 0, r6, c13, c0, 0 @ PID
mrc p15, 0, r7, c3, c0, 0 @ domain ID
- mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg
- mrc p15, 0, r9, c1, c0, 0 @ control reg
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
bic r4, r4, #2 @ clear frequency change bit
- stmia r0, {r4 - r9} @ store cp regs
- ldmia sp!, {r4 - r9, pc}
+ stmia r0, {r4 - r10} @ store cp regs
+ ldmia sp!, {r4 - r10, pc}
ENDPROC(cpu_xsc3_do_suspend)
ENTRY(cpu_xsc3_do_resume)
- ldmia r0, {r4 - r9} @ load cp regs
+ ldmia r0, {r4 - r10} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
@@ -432,10 +433,15 @@ ENTRY(cpu_xsc3_do_resume)
mcr p15, 0, r5, c15, c1, 0 @ CP access reg
mcr p15, 0, r6, c13, c0, 0 @ PID
mcr p15, 0, r7, c3, c0, 0 @ domain ID
- orr r1, r1, #0x18 @ cache the page table in L2
- mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
- mov r0, r9 @ control register
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+
+ @ temporarily map resume_turn_on_mmu into the page table,
+ @ otherwise prefetch abort occurs after MMU is turned on
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =0x542e @ section flags
b cpu_resume_mmu
ENDPROC(cpu_xsc3_do_resume)
#endif
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 2b41525..b0fe4b1 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -520,23 +520,24 @@ ENTRY(cpu_xscale_set_pte_ext)
.align
.globl cpu_xscale_suspend_size
-.equ cpu_xscale_suspend_size, 4 * 6
+.equ cpu_xscale_suspend_size, 4 * 7
#ifdef CONFIG_PM_SLEEP
ENTRY(cpu_xscale_do_suspend)
- stmfd sp!, {r4 - r9, lr}
+ stmfd sp!, {r4 - r10, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
mrc p15, 0, r5, c15, c1, 0 @ CP access reg
mrc p15, 0, r6, c13, c0, 0 @ PID
mrc p15, 0, r7, c3, c0, 0 @ domain ID
- mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg
- mrc p15, 0, r9, c1, c0, 0 @ control reg
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
bic r4, r4, #2 @ clear frequency change bit
- stmia r0, {r4 - r9} @ store cp regs
- ldmfd sp!, {r4 - r9, pc}
+ stmia r0, {r4 - r10} @ store cp regs
+ ldmfd sp!, {r4 - r10, pc}
ENDPROC(cpu_xscale_do_suspend)
ENTRY(cpu_xscale_do_resume)
- ldmia r0, {r4 - r9} @ load cp regs
+ ldmia r0, {r4 - r10} @ load cp regs
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
@@ -544,9 +545,13 @@ ENTRY(cpu_xscale_do_resume)
mcr p15, 0, r5, c15, c1, 0 @ CP access reg
mcr p15, 0, r6, c13, c0, 0 @ PID
mcr p15, 0, r7, c3, c0, 0 @ domain ID
- mcr p15, 0, r1, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg
- mov r0, r9 @ control register
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
b cpu_resume_mmu
ENDPROC(cpu_xscale_do_resume)
#endif
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 4e0a371..485e58b 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -58,6 +58,13 @@ static int report_trace(struct stackframe *frame, void *d)
return *depth == 0;
}
+#ifdef CONFIG_ANDROID
+/* Android has a different stack frame than Linux */
+struct frame_tail {
+ unsigned long fp;
+ unsigned long lr;
+} __attribute__((packed));
+#else
/*
* The registers we're interested in are at the end of the variable
* length saved register structure. The fp points at the end of this
@@ -69,6 +76,7 @@ struct frame_tail {
unsigned long sp;
unsigned long lr;
} __attribute__((packed));
+#endif
static struct frame_tail* user_backtrace(struct frame_tail *tail)
{
@@ -84,15 +92,29 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail)
/* frame pointers should strictly progress back up the stack
* (towards higher addresses) */
+#ifdef CONFIG_ANDROID
+ if (tail >= (struct frame_tail *) buftail[0].fp)
+#else
if (tail + 1 >= buftail[0].fp)
+#endif
return NULL;
+#ifdef CONFIG_ANDROID
+ /* Android has a different stack frame than Linux */
+ return (struct frame_tail *) (buftail[0].fp - sizeof(unsigned long));
+#else
return buftail[0].fp-1;
+#endif
}
static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
{
+#ifdef CONFIG_ANDROID
+ struct frame_tail *tail = (struct frame_tail *)
+ (regs->ARM_fp - sizeof(unsigned long));
+#else
struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+#endif
if (!user_mode(regs)) {
struct stackframe frame;
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index e381dc6..462a94d 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/cpu.h>
+#include <linux/hardirq.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
#include <linux/signal.h>
@@ -425,7 +426,10 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
static void vfp_enable(void *unused)
{
- u32 access = get_copro_access();
+ u32 access;
+
+ BUG_ON(preemptible());
+ access = get_copro_access();
/*
* Enable full access to VFP (cp10 and cp11)
@@ -575,7 +579,7 @@ static int __init vfp_init(void)
unsigned int cpu_arch = cpu_architecture();
if (cpu_arch >= CPU_ARCH_ARMv6)
- vfp_enable(NULL);
+ on_each_cpu(vfp_enable, NULL, 1);
/*
* First check that there is a VFP that we can use.
@@ -596,8 +600,6 @@ static int __init vfp_init(void)
} else {
hotcpu_notifier(vfp_hotplug, 0);
- smp_call_function(vfp_enable, NULL, 1);
-
VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index 0f6c7fb..9ef0a53 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -14,5 +14,8 @@ config REGMAP_I2C
config REGMAP_SPI
tristate
+config REGMAP_MMIO
+ tristate
+
config REGMAP_IRQ
bool
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index defd579..5e75d1b 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o
obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
+obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index abd7667..d92e9b1 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -26,21 +26,29 @@ struct regmap_format {
size_t val_bytes;
void (*format_write)(struct regmap *map,
unsigned int reg, unsigned int val);
- void (*format_reg)(void *buf, unsigned int reg);
- void (*format_val)(void *buf, unsigned int val);
+ void (*format_reg)(void *buf, unsigned int reg, unsigned int shift);
+ void (*format_val)(void *buf, unsigned int val, unsigned int shift);
unsigned int (*parse_val)(void *buf);
};
+typedef void (*regmap_lock)(struct regmap *map);
+typedef void (*regmap_unlock)(struct regmap *map);
+
struct regmap {
- struct mutex lock;
+ struct mutex mutex;
+ spinlock_t spinlock;
+ regmap_lock lock;
+ regmap_unlock unlock;
struct device *dev; /* Device we do I/O on */
void *work_buf; /* Scratch buffer used to format I/O */
struct regmap_format format; /* Buffer format */
const struct regmap_bus *bus;
+ void *bus_context;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
+ const char *debugfs_name;
#endif
unsigned int max_register;
@@ -52,6 +60,10 @@ struct regmap {
u8 read_flag_mask;
u8 write_flag_mask;
+ /* number of bits to (left) shift the reg value when formatting*/
+ int reg_shift;
+ int reg_stride;
+
/* regcache specific members */
const struct regcache_ops *cache_ops;
enum regcache_type cache_type;
@@ -88,7 +100,7 @@ struct regcache_ops {
int (*exit)(struct regmap *map);
int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
int (*write)(struct regmap *map, unsigned int reg, unsigned int value);
- int (*sync)(struct regmap *map);
+ int (*sync)(struct regmap *map, unsigned int min, unsigned int max);
};
bool regmap_writeable(struct regmap *map, unsigned int reg);
@@ -101,11 +113,11 @@ int _regmap_write(struct regmap *map, unsigned int reg,
#ifdef CONFIG_DEBUG_FS
extern void regmap_debugfs_initcall(void);
-extern void regmap_debugfs_init(struct regmap *map);
+extern void regmap_debugfs_init(struct regmap *map, const char *name);
extern void regmap_debugfs_exit(struct regmap *map);
#else
static inline void regmap_debugfs_initcall(void) { }
-static inline void regmap_debugfs_init(struct regmap *map) { }
+static inline void regmap_debugfs_init(struct regmap *map, const char *name) { }
static inline void regmap_debugfs_exit(struct regmap *map) { }
#endif
diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c
index b7d1614..9b36703 100644
--- a/drivers/base/regmap/regcache-lzo.c
+++ b/drivers/base/regmap/regcache-lzo.c
@@ -107,7 +107,7 @@ static int regcache_lzo_decompress_cache_block(struct regmap *map,
static inline int regcache_lzo_get_blkindex(struct regmap *map,
unsigned int reg)
{
- return (reg * map->cache_word_size) /
+ return ((reg / map->reg_stride) * map->cache_word_size) /
DIV_ROUND_UP(map->cache_size_raw,
regcache_lzo_block_count(map));
}
@@ -115,9 +115,10 @@ static inline int regcache_lzo_get_blkindex(struct regmap *map,
static inline int regcache_lzo_get_blkpos(struct regmap *map,
unsigned int reg)
{
- return reg % (DIV_ROUND_UP(map->cache_size_raw,
- regcache_lzo_block_count(map)) /
- map->cache_word_size);
+ return (reg / map->reg_stride) %
+ (DIV_ROUND_UP(map->cache_size_raw,
+ regcache_lzo_block_count(map)) /
+ map->cache_word_size);
}
static inline int regcache_lzo_get_blksize(struct regmap *map)
@@ -321,7 +322,7 @@ static int regcache_lzo_write(struct regmap *map,
}
/* set the bit so we know we have to sync this register */
- set_bit(reg, lzo_block->sync_bmp);
+ set_bit(reg / map->reg_stride, lzo_block->sync_bmp);
kfree(tmp_dst);
kfree(lzo_block->src);
return 0;
@@ -331,7 +332,8 @@ out:
return ret;
}
-static int regcache_lzo_sync(struct regmap *map)
+static int regcache_lzo_sync(struct regmap *map, unsigned int min,
+ unsigned int max)
{
struct regcache_lzo_ctx **lzo_blocks;
unsigned int val;
@@ -339,10 +341,21 @@ static int regcache_lzo_sync(struct regmap *map)
int ret;
lzo_blocks = map->cache;
- for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
+ i = min;
+ for_each_set_bit_from(i, lzo_blocks[0]->sync_bmp,
+ lzo_blocks[0]->sync_bmp_nbits) {
+ if (i > max)
+ continue;
+
ret = regcache_read(map, i, &val);
if (ret)
return ret;
+
+ /* Is this the hardware default? If so skip. */
+ ret = regcache_lookup_reg(map, i);
+ if (ret > 0 && val == map->reg_defaults[ret].def)
+ continue;
+
map->cache_bypass = 1;
ret = _regmap_write(map, i, val);
map->cache_bypass = 0;
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 32620c4..be7b068 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -38,11 +38,12 @@ struct regcache_rbtree_ctx {
};
static inline void regcache_rbtree_get_base_top_reg(
+ struct regmap *map,
struct regcache_rbtree_node *rbnode,
unsigned int *base, unsigned int *top)
{
*base = rbnode->base_reg;
- *top = rbnode->base_reg + rbnode->blklen - 1;
+ *top = rbnode->base_reg + ((rbnode->blklen - 1) * map->reg_stride);
}
static unsigned int regcache_rbtree_get_register(
@@ -69,7 +70,8 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map,
rbnode = rbtree_ctx->cached_rbnode;
if (rbnode) {
- regcache_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
+ regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg,
+ &top_reg);
if (reg >= base_reg && reg <= top_reg)
return rbnode;
}
@@ -77,7 +79,8 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map,
node = rbtree_ctx->root.rb_node;
while (node) {
rbnode = container_of(node, struct regcache_rbtree_node, node);
- regcache_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
+ regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg,
+ &top_reg);
if (reg >= base_reg && reg <= top_reg) {
rbtree_ctx->cached_rbnode = rbnode;
return rbnode;
@@ -91,7 +94,7 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map,
return NULL;
}
-static int regcache_rbtree_insert(struct rb_root *root,
+static int regcache_rbtree_insert(struct regmap *map, struct rb_root *root,
struct regcache_rbtree_node *rbnode)
{
struct rb_node **new, *parent;
@@ -105,7 +108,7 @@ static int regcache_rbtree_insert(struct rb_root *root,
rbnode_tmp = container_of(*new, struct regcache_rbtree_node,
node);
/* base and top registers of the current rbnode */
- regcache_rbtree_get_base_top_reg(rbnode_tmp, &base_reg_tmp,
+ regcache_rbtree_get_base_top_reg(map, rbnode_tmp, &base_reg_tmp,
&top_reg_tmp);
/* base register of the rbnode to be added */
base_reg = rbnode->base_reg;
@@ -137,24 +140,31 @@ static int rbtree_show(struct seq_file *s, void *ignored)
unsigned int base, top;
int nodes = 0;
int registers = 0;
+ int this_registers, average;
- mutex_lock(&map->lock);
+ map->lock(map);
for (node = rb_first(&rbtree_ctx->root); node != NULL;
node = rb_next(node)) {
n = container_of(node, struct regcache_rbtree_node, node);
- regcache_rbtree_get_base_top_reg(n, &base, &top);
- seq_printf(s, "%x-%x (%d)\n", base, top, top - base + 1);
+ regcache_rbtree_get_base_top_reg(map, n, &base, &top);
+ this_registers = ((top - base) / map->reg_stride) + 1;
+ seq_printf(s, "%x-%x (%d)\n", base, top, this_registers);
nodes++;
- registers += top - base + 1;
+ registers += this_registers;
}
+ if (nodes)
+ average = registers / nodes;
+ else
+ average = 0;
+
seq_printf(s, "%d nodes, %d registers, average %d registers\n",
- nodes, registers, registers / nodes);
+ nodes, registers, average);
- mutex_unlock(&map->lock);
+ map->unlock(map);
return 0;
}
@@ -248,7 +258,7 @@ static int regcache_rbtree_read(struct regmap *map,
rbnode = regcache_rbtree_lookup(map, reg);
if (rbnode) {
- reg_tmp = reg - rbnode->base_reg;
+ reg_tmp = (reg - rbnode->base_reg) / map->reg_stride;
*value = regcache_rbtree_get_register(rbnode, reg_tmp,
map->cache_word_size);
} else {
@@ -303,7 +313,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
*/
rbnode = regcache_rbtree_lookup(map, reg);
if (rbnode) {
- reg_tmp = reg - rbnode->base_reg;
+ reg_tmp = (reg - rbnode->base_reg) / map->reg_stride;
val = regcache_rbtree_get_register(rbnode, reg_tmp,
map->cache_word_size);
if (val == value)
@@ -314,13 +324,15 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
/* look for an adjacent register to the one we are about to add */
for (node = rb_first(&rbtree_ctx->root); node;
node = rb_next(node)) {
- rbnode_tmp = rb_entry(node, struct regcache_rbtree_node, node);
+ rbnode_tmp = rb_entry(node, struct regcache_rbtree_node,
+ node);
for (i = 0; i < rbnode_tmp->blklen; i++) {
- reg_tmp = rbnode_tmp->base_reg + i;
- if (abs(reg_tmp - reg) != 1)
+ reg_tmp = rbnode_tmp->base_reg +
+ (i * map->reg_stride);
+ if (abs(reg_tmp - reg) != map->reg_stride)
continue;
/* decide where in the block to place our register */
- if (reg_tmp + 1 == reg)
+ if (reg_tmp + map->reg_stride == reg)
pos = i + 1;
else
pos = i;
@@ -350,14 +362,15 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
return -ENOMEM;
}
regcache_rbtree_set_register(rbnode, 0, value, map->cache_word_size);
- regcache_rbtree_insert(&rbtree_ctx->root, rbnode);
+ regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode);
rbtree_ctx->cached_rbnode = rbnode;
}
return 0;
}
-static int regcache_rbtree_sync(struct regmap *map)
+static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
+ unsigned int max)
{
struct regcache_rbtree_ctx *rbtree_ctx;
struct rb_node *node;
@@ -365,19 +378,37 @@ static int regcache_rbtree_sync(struct regmap *map)
unsigned int regtmp;
unsigned int val;
int ret;
- int i;
+ int i, base, end;
rbtree_ctx = map->cache;
for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
rbnode = rb_entry(node, struct regcache_rbtree_node, node);
- for (i = 0; i < rbnode->blklen; i++) {
- regtmp = rbnode->base_reg + i;
+
+ if (rbnode->base_reg < min)
+ continue;
+ if (rbnode->base_reg > max)
+ break;
+ if (rbnode->base_reg + rbnode->blklen < min)
+ continue;
+
+ if (min > rbnode->base_reg)
+ base = min - rbnode->base_reg;
+ else
+ base = 0;
+
+ if (max < rbnode->base_reg + rbnode->blklen)
+ end = rbnode->base_reg + rbnode->blklen - max;
+ else
+ end = rbnode->blklen;
+
+ for (i = base; i < end; i++) {
+ regtmp = rbnode->base_reg + (i * map->reg_stride);
val = regcache_rbtree_get_register(rbnode, i,
map->cache_word_size);
/* Is this the hardware default? If so skip. */
- ret = regcache_lookup_reg(map, i);
- if (ret > 0 && val == map->reg_defaults[ret].def)
+ ret = regcache_lookup_reg(map, regtmp);
+ if (ret >= 0 && val == map->reg_defaults[ret].def)
continue;
map->cache_bypass = 1;
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 86cc342..bb9701d 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -57,7 +57,7 @@ static int regcache_hw_init(struct regmap *map)
for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) {
val = regcache_get_val(map->reg_defaults_raw,
i, map->cache_word_size);
- if (regmap_volatile(map, i))
+ if (regmap_volatile(map, i * map->reg_stride))
continue;
count++;
}
@@ -74,9 +74,9 @@ static int regcache_hw_init(struct regmap *map)
for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
val = regcache_get_val(map->reg_defaults_raw,
i, map->cache_word_size);
- if (regmap_volatile(map, i))
+ if (regmap_volatile(map, i * map->reg_stride))
continue;
- map->reg_defaults[j].reg = i;
+ map->reg_defaults[j].reg = i * map->reg_stride;
map->reg_defaults[j].def = val;
j++;
}
@@ -96,6 +96,10 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
int i;
void *tmp_buf;
+ for (i = 0; i < config->num_reg_defaults; i++)
+ if (config->reg_defaults[i].reg % map->reg_stride)
+ return -EINVAL;
+
if (map->cache_type == REGCACHE_NONE) {
map->cache_bypass = true;
return 0;
@@ -256,14 +260,13 @@ int regcache_write(struct regmap *map,
int regcache_sync(struct regmap *map)
{
int ret = 0;
- unsigned int val;
unsigned int i;
const char *name;
unsigned int bypass;
- BUG_ON(!map->cache_ops);
+ BUG_ON(!map->cache_ops || !map->cache_ops->sync);
- mutex_lock(&map->lock);
+ map->lock(map);
/* Remember the initial bypass state */
bypass = map->cache_bypass;
dev_dbg(map->dev, "Syncing %s cache\n",
@@ -277,6 +280,10 @@ int regcache_sync(struct regmap *map)
/* Apply any patch first */
map->cache_bypass = 1;
for (i = 0; i < map->patch_regs; i++) {
+ if (map->patch[i].reg % map->reg_stride) {
+ ret = -EINVAL;
+ goto out;
+ }
ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
if (ret != 0) {
dev_err(map->dev, "Failed to write %x = %x: %d\n",
@@ -286,35 +293,68 @@ int regcache_sync(struct regmap *map)
}
map->cache_bypass = 0;
- if (map->cache_ops->sync) {
- ret = map->cache_ops->sync(map);
- } else {
- for (i = 0; i < map->num_reg_defaults; i++) {
- ret = regcache_read(map, i, &val);
- if (ret < 0)
- goto out;
- map->cache_bypass = 1;
- ret = _regmap_write(map, i, val);
- map->cache_bypass = 0;
- if (ret < 0)
- goto out;
- dev_dbg(map->dev, "Synced register %#x, value %#x\n",
- map->reg_defaults[i].reg,
- map->reg_defaults[i].def);
- }
+ ret = map->cache_ops->sync(map, 0, map->max_register);
+
+ if (ret == 0)
+ map->cache_dirty = false;
- }
out:
trace_regcache_sync(map->dev, name, "stop");
/* Restore the bypass state */
map->cache_bypass = bypass;
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
EXPORT_SYMBOL_GPL(regcache_sync);
/**
+ * regcache_sync_region: Sync part of the register cache with the hardware.
+ *
+ * @map: map to sync.
+ * @min: first register to sync
+ * @max: last register to sync
+ *
+ * Write all non-default register values in the specified region to
+ * the hardware.
+ *
+ * Return a negative value on failure, 0 on success.
+ */
+int regcache_sync_region(struct regmap *map, unsigned int min,
+ unsigned int max)
+{
+ int ret = 0;
+ const char *name;
+ unsigned int bypass;
+
+ BUG_ON(!map->cache_ops || !map->cache_ops->sync);
+
+ map->lock(map);
+
+ /* Remember the initial bypass state */
+ bypass = map->cache_bypass;
+
+ name = map->cache_ops->name;
+ dev_dbg(map->dev, "Syncing %s cache from %d-%d\n", name, min, max);
+
+ trace_regcache_sync(map->dev, name, "start region");
+
+ if (!map->cache_dirty)
+ goto out;
+
+ ret = map->cache_ops->sync(map, min, max);
+
+out:
+ trace_regcache_sync(map->dev, name, "stop region");
+ /* Restore the bypass state */
+ map->cache_bypass = bypass;
+ map->unlock(map);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(regcache_sync_region);
+
+/**
* regcache_cache_only: Put a register map into cache only mode
*
* @map: map to configure
@@ -328,10 +368,11 @@ EXPORT_SYMBOL_GPL(regcache_sync);
*/
void regcache_cache_only(struct regmap *map, bool enable)
{
- mutex_lock(&map->lock);
+ map->lock(map);
WARN_ON(map->cache_bypass && enable);
map->cache_only = enable;
- mutex_unlock(&map->lock);
+ trace_regmap_cache_only(map->dev, enable);
+ map->unlock(map);
}
EXPORT_SYMBOL_GPL(regcache_cache_only);
@@ -346,9 +387,9 @@ EXPORT_SYMBOL_GPL(regcache_cache_only);
*/
void regcache_mark_dirty(struct regmap *map)
{
- mutex_lock(&map->lock);
+ map->lock(map);
map->cache_dirty = true;
- mutex_unlock(&map->lock);
+ map->unlock(map);
}
EXPORT_SYMBOL_GPL(regcache_mark_dirty);
@@ -365,10 +406,11 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty);
*/
void regcache_cache_bypass(struct regmap *map, bool enable)
{
- mutex_lock(&map->lock);
+ map->lock(map);
WARN_ON(map->cache_only && enable);
map->cache_bypass = enable;
- mutex_unlock(&map->lock);
+ trace_regmap_cache_bypass(map->dev, enable);
+ map->unlock(map);
}
EXPORT_SYMBOL_GPL(regcache_cache_bypass);
@@ -390,6 +432,13 @@ bool regcache_set_val(void *base, unsigned int idx,
cache[idx] = val;
break;
}
+ case 4: {
+ u32 *cache = base;
+ if (cache[idx] == val)
+ return true;
+ cache[idx] = val;
+ break;
+ }
default:
BUG();
}
@@ -411,6 +460,10 @@ unsigned int regcache_get_val(const void *base, unsigned int idx,
const u16 *cache = base;
return cache[idx];
}
+ case 4: {
+ const u32 *cache = base;
+ return cache[idx];
+ }
default:
BUG();
}
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index b3b4b8f..3403803 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -11,7 +11,6 @@
*/
#include <linux/slab.h>
-#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
@@ -33,6 +32,35 @@ static int regmap_open_file(struct inode *inode, struct file *file)
return 0;
}
+static ssize_t regmap_name_read_file(struct file *file,
+ char __user *user_buf, size_t count,
+ loff_t *ppos)
+{
+ struct regmap *map = file->private_data;
+ int ret;
+ char *buf;
+
+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name);
+ if (ret < 0) {
+ kfree(buf);
+ return ret;
+ }
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+ kfree(buf);
+ return ret;
+}
+
+static const struct file_operations regmap_name_fops = {
+ .open = regmap_open_file,
+ .read = regmap_name_read_file,
+ .llseek = default_llseek,
+};
+
static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -57,7 +85,7 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
val_len = 2 * map->format.val_bytes;
tot_len = reg_len + val_len + 3; /* : \n */
- for (i = 0; i < map->max_register + 1; i++) {
+ for (i = 0; i <= map->max_register; i += map->reg_stride) {
if (!regmap_readable(map, i))
continue;
@@ -103,9 +131,51 @@ out:
return ret;
}
+#undef REGMAP_ALLOW_WRITE_DEBUGFS
+#ifdef REGMAP_ALLOW_WRITE_DEBUGFS
+/*
+ * This can be dangerous especially when we have clients such as
+ * PMICs, therefore don't provide any real compile time configuration option
+ * for this feature, people who want to use this will need to modify
+ * the source code directly.
+ */
+static ssize_t regmap_map_write_file(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char buf[32];
+ size_t buf_size;
+ char *start = buf;
+ unsigned long reg, value;
+ struct regmap *map = file->private_data;
+
+ buf_size = min(count, (sizeof(buf)-1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ while (*start == ' ')
+ start++;
+ reg = simple_strtoul(start, &start, 16);
+ while (*start == ' ')
+ start++;
+ if (strict_strtoul(start, 16, &value))
+ return -EINVAL;
+
+ /* Userspace has been fiddling around behind the kernel's back */
+ add_taint(TAINT_USER);
+
+ regmap_write(map, reg, value);
+ return buf_size;
+}
+#else
+#define regmap_map_write_file NULL
+#endif
+
static const struct file_operations regmap_map_fops = {
.open = regmap_open_file,
.read = regmap_map_read_file,
+ .write = regmap_map_write_file,
.llseek = default_llseek,
};
@@ -132,7 +202,7 @@ static ssize_t regmap_access_read_file(struct file *file,
reg_len = regmap_calc_reg_len(map->max_register, buf, count);
tot_len = reg_len + 10; /* ': R W V P\n' */
- for (i = 0; i < map->max_register + 1; i++) {
+ for (i = 0; i <= map->max_register; i += map->reg_stride) {
/* Ignore registers which are neither readable nor writable */
if (!regmap_readable(map, i) && !regmap_writeable(map, i))
continue;
@@ -177,15 +247,25 @@ static const struct file_operations regmap_access_fops = {
.llseek = default_llseek,
};
-void regmap_debugfs_init(struct regmap *map)
+void regmap_debugfs_init(struct regmap *map, const char *name)
{
- map->debugfs = debugfs_create_dir(dev_name(map->dev),
- regmap_debugfs_root);
+ if (name) {
+ map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
+ dev_name(map->dev), name);
+ name = map->debugfs_name;
+ } else {
+ name = dev_name(map->dev);
+ }
+
+ map->debugfs = debugfs_create_dir(name, regmap_debugfs_root);
if (!map->debugfs) {
dev_warn(map->dev, "Failed to create debugfs directory\n");
return;
}
+ debugfs_create_file("name", 0400, map->debugfs,
+ map, &regmap_name_fops);
+
if (map->max_register) {
debugfs_create_file("registers", 0400, map->debugfs,
map, &regmap_map_fops);
@@ -206,6 +286,7 @@ void regmap_debugfs_init(struct regmap *map)
void regmap_debugfs_exit(struct regmap *map)
{
debugfs_remove_recursive(map->debugfs);
+ kfree(map->debugfs_name);
}
void regmap_debugfs_initcall(void)
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 9a3a8c5..5f6b247 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -15,8 +15,9 @@
#include <linux/module.h>
#include <linux/init.h>
-static int regmap_i2c_write(struct device *dev, const void *data, size_t count)
+static int regmap_i2c_write(void *context, const void *data, size_t count)
{
+ struct device *dev = context;
struct i2c_client *i2c = to_i2c_client(dev);
int ret;
@@ -29,10 +30,11 @@ static int regmap_i2c_write(struct device *dev, const void *data, size_t count)
return -EIO;
}
-static int regmap_i2c_gather_write(struct device *dev,
+static int regmap_i2c_gather_write(void *context,
const void *reg, size_t reg_size,
const void *val, size_t val_size)
{
+ struct device *dev = context;
struct i2c_client *i2c = to_i2c_client(dev);
struct i2c_msg xfer[2];
int ret;
@@ -62,10 +64,11 @@ static int regmap_i2c_gather_write(struct device *dev,
return -EIO;
}
-static int regmap_i2c_read(struct device *dev,
+static int regmap_i2c_read(void *context,
const void *reg, size_t reg_size,
void *val, size_t val_size)
{
+ struct device *dev = context;
struct i2c_client *i2c = to_i2c_client(dev);
struct i2c_msg xfer[2];
int ret;
@@ -107,7 +110,7 @@ static struct regmap_bus regmap_i2c = {
struct regmap *regmap_init_i2c(struct i2c_client *i2c,
const struct regmap_config *config)
{
- return regmap_init(&i2c->dev, &regmap_i2c, config);
+ return regmap_init(&i2c->dev, &regmap_i2c, &i2c->dev, config);
}
EXPORT_SYMBOL_GPL(regmap_init_i2c);
@@ -124,7 +127,7 @@ EXPORT_SYMBOL_GPL(regmap_init_i2c);
struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
const struct regmap_config *config)
{
- return devm_regmap_init(&i2c->dev, &regmap_i2c, config);
+ return devm_regmap_init(&i2c->dev, &regmap_i2c, &i2c->dev, config);
}
EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 428836f..cc7b4f7 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -49,6 +49,7 @@ static void regmap_irq_lock(struct irq_data *data)
static void regmap_irq_sync_unlock(struct irq_data *data)
{
struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
+ struct regmap *map = d->map;
int i, ret;
/*
@@ -57,11 +58,12 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
* suppress pointless writes.
*/
for (i = 0; i < d->chip->num_regs; i++) {
- ret = regmap_update_bits(d->map, d->chip->mask_base + i,
+ ret = regmap_update_bits(d->map, d->chip->mask_base +
+ (i * map->reg_stride),
d->mask_buf_def[i], d->mask_buf[i]);
if (ret != 0)
dev_err(d->map->dev, "Failed to sync masks in %x\n",
- d->chip->mask_base + i);
+ d->chip->mask_base + (i * map->reg_stride));
}
mutex_unlock(&d->lock);
@@ -70,17 +72,19 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
static void regmap_irq_enable(struct irq_data *data)
{
struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
+ struct regmap *map = d->map;
const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq);
- d->mask_buf[irq_data->reg_offset] &= ~irq_data->mask;
+ d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask;
}
static void regmap_irq_disable(struct irq_data *data)
{
struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
+ struct regmap *map = d->map;
const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq);
- d->mask_buf[irq_data->reg_offset] |= irq_data->mask;
+ d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask;
}
static struct irq_chip regmap_irq_chip = {
@@ -135,17 +139,19 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
data->status_buf[i] &= ~data->mask_buf[i];
if (data->status_buf[i] && chip->ack_base) {
- ret = regmap_write(map, chip->ack_base + i,
+ ret = regmap_write(map, chip->ack_base +
+ (i * map->reg_stride),
data->status_buf[i]);
if (ret != 0)
dev_err(map->dev, "Failed to ack 0x%x: %d\n",
- chip->ack_base + i, ret);
+ chip->ack_base + (i * map->reg_stride),
+ ret);
}
}
for (i = 0; i < chip->num_irqs; i++) {
- if (data->status_buf[chip->irqs[i].reg_offset] &
- chip->irqs[i].mask) {
+ if (data->status_buf[chip->irqs[i].reg_offset /
+ map->reg_stride] & chip->irqs[i].mask) {
handle_nested_irq(data->irq_base + i);
handled = true;
}
@@ -180,6 +186,14 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
int cur_irq, i;
int ret = -ENOMEM;
+ for (i = 0; i < chip->num_irqs; i++) {
+ if (chip->irqs[i].reg_offset % map->reg_stride)
+ return -EINVAL;
+ if (chip->irqs[i].reg_offset / map->reg_stride >=
+ chip->num_regs)
+ return -EINVAL;
+ }
+
irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0);
if (irq_base < 0) {
dev_warn(map->dev, "Failed to allocate IRQs: %d\n",
@@ -217,16 +231,17 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
mutex_init(&d->lock);
for (i = 0; i < chip->num_irqs; i++)
- d->mask_buf_def[chip->irqs[i].reg_offset]
+ d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride]
|= chip->irqs[i].mask;
/* Mask all the interrupts by default */
for (i = 0; i < chip->num_regs; i++) {
d->mask_buf[i] = d->mask_buf_def[i];
- ret = regmap_write(map, chip->mask_base + i, d->mask_buf[i]);
+ ret = regmap_write(map, chip->mask_base + (i * map->reg_stride),
+ d->mask_buf[i]);
if (ret != 0) {
dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
- chip->mask_base + i, ret);
+ chip->mask_base + (i * map->reg_stride), ret);
goto err_alloc;
}
}
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c
new file mode 100644
index 00000000..febd6de
--- /dev/null
+++ b/drivers/base/regmap/regmap-mmio.c
@@ -0,0 +1,224 @@
+/*
+ * Register map access API - MMIO support
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+struct regmap_mmio_context {
+ void __iomem *regs;
+ unsigned val_bytes;
+};
+
+static int regmap_mmio_gather_write(void *context,
+ const void *reg, size_t reg_size,
+ const void *val, size_t val_size)
+{
+ struct regmap_mmio_context *ctx = context;
+ u32 offset;
+
+ BUG_ON(reg_size != 4);
+
+ offset = be32_to_cpup(reg);
+
+ while (val_size) {
+ switch (ctx->val_bytes) {
+ case 1:
+ writeb(*(u8 *)val, ctx->regs + offset);
+ break;
+ case 2:
+ writew(be16_to_cpup(val), ctx->regs + offset);
+ break;
+ case 4:
+ writel(be32_to_cpup(val), ctx->regs + offset);
+ break;
+#ifdef CONFIG_64BIT
+ case 8:
+ writeq(be64_to_cpup(val), ctx->regs + offset);
+ break;
+#endif
+ default:
+ /* Should be caught by regmap_mmio_check_config */
+ BUG();
+ }
+ val_size -= ctx->val_bytes;
+ val += ctx->val_bytes;
+ offset += ctx->val_bytes;
+ }
+
+ return 0;
+}
+
+static int regmap_mmio_write(void *context, const void *data, size_t count)
+{
+ BUG_ON(count < 4);
+
+ return regmap_mmio_gather_write(context, data, 4, data + 4, count - 4);
+}
+
+static int regmap_mmio_read(void *context,
+ const void *reg, size_t reg_size,
+ void *val, size_t val_size)
+{
+ struct regmap_mmio_context *ctx = context;
+ u32 offset;
+
+ BUG_ON(reg_size != 4);
+
+ offset = be32_to_cpup(reg);
+
+ while (val_size) {
+ switch (ctx->val_bytes) {
+ case 1:
+ *(u8 *)val = readb(ctx->regs + offset);
+ break;
+ case 2:
+ *(u16 *)val = cpu_to_be16(readw(ctx->regs + offset));
+ break;
+ case 4:
+ *(u32 *)val = cpu_to_be32(readl(ctx->regs + offset));
+ break;
+#ifdef CONFIG_64BIT
+ case 8:
+ *(u64 *)val = cpu_to_be32(readq(ctx->regs + offset));
+ break;
+#endif
+ default:
+ /* Should be caught by regmap_mmio_check_config */
+ BUG();
+ }
+ val_size -= ctx->val_bytes;
+ val += ctx->val_bytes;
+ offset += ctx->val_bytes;
+ }
+
+ return 0;
+}
+
+static void regmap_mmio_free_context(void *context)
+{
+ kfree(context);
+}
+
+static struct regmap_bus regmap_mmio = {
+ .fast_io = true,
+ .write = regmap_mmio_write,
+ .gather_write = regmap_mmio_gather_write,
+ .read = regmap_mmio_read,
+ .free_context = regmap_mmio_free_context,
+};
+
+struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs,
+ const struct regmap_config *config)
+{
+ struct regmap_mmio_context *ctx;
+ int min_stride;
+
+ if (config->reg_bits != 32)
+ return ERR_PTR(-EINVAL);
+
+ if (config->pad_bits)
+ return ERR_PTR(-EINVAL);
+
+ switch (config->val_bits) {
+ case 8:
+ /* The core treats 0 as 1 */
+ min_stride = 0;
+ break;
+ case 16:
+ min_stride = 2;
+ break;
+ case 32:
+ min_stride = 4;
+ break;
+#ifdef CONFIG_64BIT
+ case 64:
+ min_stride = 8;
+ break;
+#endif
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (config->reg_stride < min_stride)
+ return ERR_PTR(-EINVAL);
+
+ ctx = kzalloc(GFP_KERNEL, sizeof(*ctx));
+ if (!ctx)
+ return ERR_PTR(-ENOMEM);
+
+ ctx->regs = regs;
+ ctx->val_bytes = config->val_bits / 8;
+
+ return ctx;
+}
+
+/**
+ * regmap_init_mmio(): Initialise register map
+ *
+ * @dev: Device that will be interacted with
+ * @regs: Pointer to memory-mapped IO region
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+struct regmap *regmap_init_mmio(struct device *dev,
+ void __iomem *regs,
+ const struct regmap_config *config)
+{
+ struct regmap_mmio_context *ctx;
+
+ ctx = regmap_mmio_gen_context(regs, config);
+ if (IS_ERR(ctx))
+ return ERR_CAST(ctx);
+
+ return regmap_init(dev, &regmap_mmio, ctx, config);
+}
+EXPORT_SYMBOL_GPL(regmap_init_mmio);
+
+/**
+ * devm_regmap_init_mmio(): Initialise managed register map
+ *
+ * @dev: Device that will be interacted with
+ * @regs: Pointer to memory-mapped IO region
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap. The regmap will be automatically freed by the
+ * device management code.
+ */
+struct regmap *devm_regmap_init_mmio(struct device *dev,
+ void __iomem *regs,
+ const struct regmap_config *config)
+{
+ struct regmap_mmio_context *ctx;
+
+ ctx = regmap_mmio_gen_context(regs, config);
+ if (IS_ERR(ctx))
+ return ERR_CAST(ctx);
+
+ return devm_regmap_init(dev, &regmap_mmio, ctx, config);
+}
+EXPORT_SYMBOL_GPL(devm_regmap_init_mmio);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c
index 7c0c35a..ffa46a9 100644
--- a/drivers/base/regmap/regmap-spi.c
+++ b/drivers/base/regmap/regmap-spi.c
@@ -15,17 +15,19 @@
#include <linux/init.h>
#include <linux/module.h>
-static int regmap_spi_write(struct device *dev, const void *data, size_t count)
+static int regmap_spi_write(void *context, const void *data, size_t count)
{
+ struct device *dev = context;
struct spi_device *spi = to_spi_device(dev);
return spi_write(spi, data, count);
}
-static int regmap_spi_gather_write(struct device *dev,
+static int regmap_spi_gather_write(void *context,
const void *reg, size_t reg_len,
const void *val, size_t val_len)
{
+ struct device *dev = context;
struct spi_device *spi = to_spi_device(dev);
struct spi_message m;
struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, },
@@ -38,10 +40,11 @@ static int regmap_spi_gather_write(struct device *dev,
return spi_sync(spi, &m);
}
-static int regmap_spi_read(struct device *dev,
+static int regmap_spi_read(void *context,
const void *reg, size_t reg_size,
void *val, size_t val_size)
{
+ struct device *dev = context;
struct spi_device *spi = to_spi_device(dev);
return spi_write_then_read(spi, reg, reg_size, val, val_size);
@@ -66,7 +69,7 @@ static struct regmap_bus regmap_spi = {
struct regmap *regmap_init_spi(struct spi_device *spi,
const struct regmap_config *config)
{
- return regmap_init(&spi->dev, &regmap_spi, config);
+ return regmap_init(&spi->dev, &regmap_spi, &spi->dev, config);
}
EXPORT_SYMBOL_GPL(regmap_init_spi);
@@ -83,7 +86,7 @@ EXPORT_SYMBOL_GPL(regmap_init_spi);
struct regmap *devm_regmap_init_spi(struct spi_device *spi,
const struct regmap_config *config)
{
- return devm_regmap_init(&spi->dev, &regmap_spi, config);
+ return devm_regmap_init(&spi->dev, &regmap_spi, &spi->dev, config);
}
EXPORT_SYMBOL_GPL(devm_regmap_init_spi);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a239ce8..1eb6de3 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -10,8 +10,9 @@
* published by the Free Software Foundation.
*/
+#include <linux/device.h>
#include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/mutex.h>
#include <linux/err.h>
@@ -111,18 +112,36 @@ static void regmap_format_10_14_write(struct regmap *map,
out[0] = reg >> 2;
}
-static void regmap_format_8(void *buf, unsigned int val)
+static void regmap_format_8(void *buf, unsigned int val, unsigned int shift)
{
u8 *b = buf;
- b[0] = val;
+ b[0] = val << shift;
}
-static void regmap_format_16(void *buf, unsigned int val)
+static void regmap_format_16(void *buf, unsigned int val, unsigned int shift)
{
__be16 *b = buf;
- b[0] = cpu_to_be16(val);
+ b[0] = cpu_to_be16(val << shift);
+}
+
+static void regmap_format_24(void *buf, unsigned int val, unsigned int shift)
+{
+ u8 *b = buf;
+
+ val <<= shift;
+
+ b[0] = val >> 16;
+ b[1] = val >> 8;
+ b[2] = val;
+}
+
+static void regmap_format_32(void *buf, unsigned int val, unsigned int shift)
+{
+ __be32 *b = buf;
+
+ b[0] = cpu_to_be32(val << shift);
}
static unsigned int regmap_parse_8(void *buf)
@@ -141,11 +160,51 @@ static unsigned int regmap_parse_16(void *buf)
return b[0];
}
+static unsigned int regmap_parse_24(void *buf)
+{
+ u8 *b = buf;
+ unsigned int ret = b[2];
+ ret |= ((unsigned int)b[1]) << 8;
+ ret |= ((unsigned int)b[0]) << 16;
+
+ return ret;
+}
+
+static unsigned int regmap_parse_32(void *buf)
+{
+ __be32 *b = buf;
+
+ b[0] = be32_to_cpu(b[0]);
+
+ return b[0];
+}
+
+static void regmap_lock_mutex(struct regmap *map)
+{
+ mutex_lock(&map->mutex);
+}
+
+static void regmap_unlock_mutex(struct regmap *map)
+{
+ mutex_unlock(&map->mutex);
+}
+
+static void regmap_lock_spinlock(struct regmap *map)
+{
+ spin_lock(&map->spinlock);
+}
+
+static void regmap_unlock_spinlock(struct regmap *map)
+{
+ spin_unlock(&map->spinlock);
+}
+
/**
* regmap_init(): Initialise register map
*
* @dev: Device that will be interacted with
* @bus: Bus-specific callbacks to use with device
+ * @bus_context: Data passed to bus-specific callbacks
* @config: Configuration for register map
*
* The return value will be an ERR_PTR() on error or a valid pointer to
@@ -154,6 +213,7 @@ static unsigned int regmap_parse_16(void *buf)
*/
struct regmap *regmap_init(struct device *dev,
const struct regmap_bus *bus,
+ void *bus_context,
const struct regmap_config *config)
{
struct regmap *map;
@@ -168,14 +228,28 @@ struct regmap *regmap_init(struct device *dev,
goto err;
}
- mutex_init(&map->lock);
+ if (bus->fast_io) {
+ spin_lock_init(&map->spinlock);
+ map->lock = regmap_lock_spinlock;
+ map->unlock = regmap_unlock_spinlock;
+ } else {
+ mutex_init(&map->mutex);
+ map->lock = regmap_lock_mutex;
+ map->unlock = regmap_unlock_mutex;
+ }
map->format.buf_size = (config->reg_bits + config->val_bits) / 8;
map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
map->format.pad_bytes = config->pad_bits / 8;
map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
map->format.buf_size += map->format.pad_bytes;
+ map->reg_shift = config->pad_bits % 8;
+ if (config->reg_stride)
+ map->reg_stride = config->reg_stride;
+ else
+ map->reg_stride = 1;
map->dev = dev;
map->bus = bus;
+ map->bus_context = bus_context;
map->max_register = config->max_register;
map->writeable_reg = config->writeable_reg;
map->readable_reg = config->readable_reg;
@@ -190,7 +264,7 @@ struct regmap *regmap_init(struct device *dev,
map->read_flag_mask = bus->read_flag_mask;
}
- switch (config->reg_bits) {
+ switch (config->reg_bits + map->reg_shift) {
case 2:
switch (config->val_bits) {
case 6:
@@ -239,6 +313,10 @@ struct regmap *regmap_init(struct device *dev,
map->format.format_reg = regmap_format_16;
break;
+ case 32:
+ map->format.format_reg = regmap_format_32;
+ break;
+
default:
goto err_map;
}
@@ -252,6 +330,14 @@ struct regmap *regmap_init(struct device *dev,
map->format.format_val = regmap_format_16;
map->format.parse_val = regmap_parse_16;
break;
+ case 24:
+ map->format.format_val = regmap_format_24;
+ map->format.parse_val = regmap_parse_24;
+ break;
+ case 32:
+ map->format.format_val = regmap_format_32;
+ map->format.parse_val = regmap_parse_32;
+ break;
}
if (!map->format.format_write &&
@@ -264,7 +350,7 @@ struct regmap *regmap_init(struct device *dev,
goto err_map;
}
- regmap_debugfs_init(map);
+ regmap_debugfs_init(map, config->name);
ret = regcache_init(map, config);
if (ret < 0)
@@ -291,6 +377,7 @@ static void devm_regmap_release(struct device *dev, void *res)
*
* @dev: Device that will be interacted with
* @bus: Bus-specific callbacks to use with device
+ * @bus_context: Data passed to bus-specific callbacks
* @config: Configuration for register map
*
* The return value will be an ERR_PTR() on error or a valid pointer
@@ -300,6 +387,7 @@ static void devm_regmap_release(struct device *dev, void *res)
*/
struct regmap *devm_regmap_init(struct device *dev,
const struct regmap_bus *bus,
+ void *bus_context,
const struct regmap_config *config)
{
struct regmap **ptr, *regmap;
@@ -308,7 +396,7 @@ struct regmap *devm_regmap_init(struct device *dev,
if (!ptr)
return ERR_PTR(-ENOMEM);
- regmap = regmap_init(dev, bus, config);
+ regmap = regmap_init(dev, bus, bus_context, config);
if (!IS_ERR(regmap)) {
*ptr = regmap;
devres_add(dev, ptr);
@@ -335,7 +423,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
{
int ret;
- mutex_lock(&map->lock);
+ map->lock(map);
regcache_exit(map);
regmap_debugfs_exit(map);
@@ -347,13 +435,14 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
map->precious_reg = config->precious_reg;
map->cache_type = config->cache_type;
+ regmap_debugfs_init(map, config->name);
+
map->cache_bypass = false;
map->cache_only = false;
- regmap_debugfs_init(map);
ret = regcache_init(map, config);
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
@@ -365,6 +454,8 @@ void regmap_exit(struct regmap *map)
{
regcache_exit(map);
regmap_debugfs_exit(map);
+ if (map->bus->free_context)
+ map->bus->free_context(map->bus_context);
kfree(map->work_buf);
kfree(map);
}
@@ -382,7 +473,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
/* Check for unwritable registers before we start */
if (map->writeable_reg)
for (i = 0; i < val_len / map->format.val_bytes; i++)
- if (!map->writeable_reg(map->dev, reg + i))
+ if (!map->writeable_reg(map->dev,
+ reg + (i * map->reg_stride)))
return -EINVAL;
if (!map->cache_bypass && map->format.parse_val) {
@@ -391,7 +483,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
for (i = 0; i < val_len / val_bytes; i++) {
memcpy(map->work_buf, val + (i * val_bytes), val_bytes);
ival = map->format.parse_val(map->work_buf);
- ret = regcache_write(map, reg + i, ival);
+ ret = regcache_write(map, reg + (i * map->reg_stride),
+ ival);
if (ret) {
dev_err(map->dev,
"Error in caching of register: %u ret: %d\n",
@@ -405,7 +498,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
}
}
- map->format.format_reg(map->work_buf, reg);
+ map->format.format_reg(map->work_buf, reg, map->reg_shift);
u8[0] |= map->write_flag_mask;
@@ -418,12 +511,12 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
*/
if (val == (map->work_buf + map->format.pad_bytes +
map->format.reg_bytes))
- ret = map->bus->write(map->dev, map->work_buf,
+ ret = map->bus->write(map->bus_context, map->work_buf,
map->format.reg_bytes +
map->format.pad_bytes +
val_len);
else if (map->bus->gather_write)
- ret = map->bus->gather_write(map->dev, map->work_buf,
+ ret = map->bus->gather_write(map->bus_context, map->work_buf,
map->format.reg_bytes +
map->format.pad_bytes,
val, val_len);
@@ -438,7 +531,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
memcpy(buf, map->work_buf, map->format.reg_bytes);
memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
val, val_len);
- ret = map->bus->write(map->dev, buf, len);
+ ret = map->bus->write(map->bus_context, buf, len);
kfree(buf);
}
@@ -472,7 +565,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
trace_regmap_hw_write_start(map->dev, reg, 1);
- ret = map->bus->write(map->dev, map->work_buf,
+ ret = map->bus->write(map->bus_context, map->work_buf,
map->format.buf_size);
trace_regmap_hw_write_done(map->dev, reg, 1);
@@ -480,7 +573,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
return ret;
} else {
map->format.format_val(map->work_buf + map->format.reg_bytes
- + map->format.pad_bytes, val);
+ + map->format.pad_bytes, val, 0);
return _regmap_raw_write(map, reg,
map->work_buf +
map->format.reg_bytes +
@@ -503,11 +596,14 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
{
int ret;
- mutex_lock(&map->lock);
+ if (reg % map->reg_stride)
+ return -EINVAL;
+
+ map->lock(map);
ret = _regmap_write(map, reg, val);
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
@@ -534,11 +630,16 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
{
int ret;
- mutex_lock(&map->lock);
+ if (val_len % map->format.val_bytes)
+ return -EINVAL;
+ if (reg % map->reg_stride)
+ return -EINVAL;
+
+ map->lock(map);
ret = _regmap_raw_write(map, reg, val, val_len);
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
@@ -567,8 +668,10 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
if (!map->format.parse_val)
return -EINVAL;
+ if (reg % map->reg_stride)
+ return -EINVAL;
- mutex_lock(&map->lock);
+ map->lock(map);
/* No formatting is require if val_byte is 1 */
if (val_bytes == 1) {
@@ -589,7 +692,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
kfree(wval);
out:
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
EXPORT_SYMBOL_GPL(regmap_bulk_write);
@@ -600,7 +703,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
u8 *u8 = map->work_buf;
int ret;
- map->format.format_reg(map->work_buf, reg);
+ map->format.format_reg(map->work_buf, reg, map->reg_shift);
/*
* Some buses or devices flag reads by setting the high bits in the
@@ -613,7 +716,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
trace_regmap_hw_read_start(map->dev, reg,
val_len / map->format.val_bytes);
- ret = map->bus->read(map->dev, map->work_buf,
+ ret = map->bus->read(map->bus_context, map->work_buf,
map->format.reg_bytes + map->format.pad_bytes,
val, val_len);
@@ -663,11 +766,14 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
{
int ret;
- mutex_lock(&map->lock);
+ if (reg % map->reg_stride)
+ return -EINVAL;
+
+ map->lock(map);
ret = _regmap_read(map, reg, val);
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
@@ -687,17 +793,39 @@ EXPORT_SYMBOL_GPL(regmap_read);
int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
size_t val_len)
{
- size_t val_count = val_len / map->format.val_bytes;
- int ret;
+ size_t val_bytes = map->format.val_bytes;
+ size_t val_count = val_len / val_bytes;
+ unsigned int v;
+ int ret, i;
- WARN_ON(!regmap_volatile_range(map, reg, val_count) &&
- map->cache_type != REGCACHE_NONE);
+ if (val_len % map->format.val_bytes)
+ return -EINVAL;
+ if (reg % map->reg_stride)
+ return -EINVAL;
- mutex_lock(&map->lock);
+ map->lock(map);
- ret = _regmap_raw_read(map, reg, val, val_len);
+ if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
+ map->cache_type == REGCACHE_NONE) {
+ /* Physical block read if there's no cache involved */
+ ret = _regmap_raw_read(map, reg, val, val_len);
- mutex_unlock(&map->lock);
+ } else {
+ /* Otherwise go word by word for the cache; should be low
+ * cost as we expect to hit the cache.
+ */
+ for (i = 0; i < val_count; i++) {
+ ret = _regmap_read(map, reg + (i * map->reg_stride),
+ &v);
+ if (ret != 0)
+ goto out;
+
+ map->format.format_val(val + (i * val_bytes), v, 0);
+ }
+ }
+
+ out:
+ map->unlock(map);
return ret;
}
@@ -723,6 +851,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
if (!map->format.parse_val)
return -EINVAL;
+ if (reg % map->reg_stride)
+ return -EINVAL;
if (vol || map->cache_type == REGCACHE_NONE) {
ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
@@ -733,7 +863,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
map->format.parse_val(val + i);
} else {
for (i = 0; i < val_count; i++) {
- ret = regmap_read(map, reg + i, val + (i * val_bytes));
+ ret = regmap_read(map, reg + (i * map->reg_stride),
+ val + (i * val_bytes));
if (ret != 0)
return ret;
}
@@ -750,7 +881,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
int ret;
unsigned int tmp, orig;
- mutex_lock(&map->lock);
+ map->lock(map);
ret = _regmap_read(map, reg, &orig);
if (ret != 0)
@@ -767,7 +898,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
}
out:
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
@@ -807,7 +938,7 @@ int regmap_update_bits_lazy(struct regmap *map, unsigned int reg,
int ret, new;
unsigned int tmp;
- mutex_lock(&map->lock);
+ map->lock(map);
ret = _regmap_read(map, reg, &tmp);
if (ret != 0)
@@ -820,7 +951,7 @@ int regmap_update_bits_lazy(struct regmap *map, unsigned int reg,
}
out:
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
@@ -869,7 +1000,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
if (map->patch)
return -EBUSY;
- mutex_lock(&map->lock);
+ map->lock(map);
bypass = map->cache_bypass;
@@ -897,12 +1028,27 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
out:
map->cache_bypass = bypass;
- mutex_unlock(&map->lock);
+ map->unlock(map);
return ret;
}
EXPORT_SYMBOL_GPL(regmap_register_patch);
+/**
+ * regmap_get_val_bytes(): Report the size of a register value
+ *
+ * Report the size of a register value, mainly intended to for use by
+ * generic infrastructure built on top of regmap.
+ */
+int regmap_get_val_bytes(struct regmap *map)
+{
+ if (map->format.format_write)
+ return -EINVAL;
+
+ return map->format.val_bytes;
+}
+EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
+
static int __init regmap_initcall(void)
{
regmap_debugfs_initcall();
diff --git a/drivers/bluetooth/ti_bluesleep.c b/drivers/bluetooth/ti_bluesleep.c
index d86fd26..2ab5324 100644
--- a/drivers/bluetooth/ti_bluesleep.c
+++ b/drivers/bluetooth/ti_bluesleep.c
@@ -31,37 +31,17 @@
*/
#include <linux/module.h> /* kernel module definitions */
-#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/notifier.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/timer.h>
-#include <linux/uaccess.h>
-#include <linux/version.h>
-#include <linux/workqueue.h>
#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/ioport.h>
-#include <linux/param.h>
-#include <linux/bitops.h>
-#include <linux/termios.h>
-#include <linux/wakelock.h>
#include <mach/gpio.h>
-#include <linux/serial_core.h>
-#include <linux/tegra_uart.h>
#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h> /* event notifications */
-#include "hci_uart.h"
/*
* Defines
*/
-
#define VERSION "1.1"
#define POLARITY_LOW 0
@@ -70,9 +50,7 @@
struct bluesleep_info {
unsigned host_wake_irq;
struct uart_port *uport;
- struct wake_lock wake_lock;
int irq_polarity;
- int has_ext_wake;
};
@@ -81,16 +59,6 @@ struct bluesleep_info {
#define BT_ACTIVE 0x02
#define BT_SUSPEND 0x04
-
-/* work function */
-static void hostwake_sleep_work(struct work_struct *work);
-
-/* work queue */
-DECLARE_DELAYED_WORK(ti_sleep_workqueue, hostwake_sleep_work);
-
-/* Macros for handling sleep work */
-#define hostwake_workqueue() schedule_delayed_work(&ti_sleep_workqueue, 0)
-
static struct bluesleep_info *bsi;
/* module usage */
@@ -102,66 +70,6 @@ static atomic_t open_count = ATOMIC_INIT(1);
/** Global state flags */
static unsigned long flags;
-/** Tasklet to respond to change in hostwake line */
-static struct tasklet_struct hostwake_task;
-
-/** Lock for state transitions */
-static spinlock_t rw_lock;
-
-/*
- * Local functions
- */
-static void hsuart_power(int on)
-{
- pr_debug("%s", __func__);
-
- if (on) {
- tegra_uart_request_clock_on(bsi->uport);
- tegra_uart_set_mctrl(bsi->uport, TIOCM_RTS);
- } else {
- tegra_uart_set_mctrl(bsi->uport, 0);
- tegra_uart_request_clock_off(bsi->uport);
- }
-}
-
-
-
-/**
- * @brief@ main sleep work handling function which update the flags
- * and activate and deactivate UART .
- */
-
-static void hostwake_sleep_work(struct work_struct *work)
-{
- pr_debug("%s", __func__);
- free_irq(bsi->host_wake_irq, "tibluesleep");
- /*Activating UART */
- if (test_bit(BT_SUSPEND, &flags)) {
- BT_DBG("Activate UART");
- hsuart_power(1);
-
- }
- bsi->has_ext_wake = 0;
- clear_bit(BT_SUSPEND, &flags);
- set_bit(BT_ACTIVE, &flags);
-
-}
-
-
-/**
- * A tasklet function that runs in tasklet context
- * @param data Not used.
- */
-static void bluesleep_hostwake_task(unsigned long data)
-{
- pr_debug("%s", __func__);
- disable_irq(bsi->host_wake_irq);
- spin_lock(&rw_lock);
- hostwake_workqueue();
- spin_unlock(&rw_lock);
-}
-
-
/**
* Schedules a tasklet to run when receiving an interrupt on the
* <code>HOST_WAKE</code> GPIO pin.
@@ -170,11 +78,8 @@ static void bluesleep_hostwake_task(unsigned long data)
*/
static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id)
{
-
pr_debug("%s", __func__);
- /* schedule a tasklet to handle the change in the host wake line */
- bsi->has_ext_wake = 1;
- tasklet_schedule(&hostwake_task);
+ disable_irq_nosync(bsi->host_wake_irq);
return IRQ_HANDLED;
}
@@ -183,8 +88,7 @@ static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id)
* @return On success, 0. On error, -1, and <code>errno</code> is set
* appropriately.
*/
-
- int bluesleep_start(struct uart_port *uport)
+int bluesleep_start(struct uart_port *uport)
{
int retval;
bsi->uport = uport;
@@ -224,9 +128,8 @@ fail:
/**
* Stops the Sleep-Mode Protocol on the Host.
*/
- void bluesleep_stop(void)
+void bluesleep_stop(void)
{
-
pr_debug("%s", __func__);
if (disable_irq_wake(bsi->host_wake_irq))
@@ -264,7 +167,6 @@ static int bluesleep_probe(struct platform_device *pdev)
else
bsi->irq_polarity = POLARITY_HIGH;/*anything else*/
- wake_lock_init(&bsi->wake_lock, WAKE_LOCK_SUSPEND, "bluesleep");
clear_bit(BT_SUSPEND, &flags);
set_bit(BT_ACTIVE, &flags);
@@ -282,17 +184,11 @@ static int bluesleep_remove(struct platform_device *pdev)
return 0;
}
-
static int bluesleep_resume(struct platform_device *pdev)
{
-
pr_debug("%s", __func__);
if (test_bit(BT_SUSPEND, &flags)) {
-
- if ((bsi->uport != NULL) && (bsi->has_ext_wake)) {
- tegra_uart_request_clock_on(bsi->uport);
- tegra_uart_set_mctrl(bsi->uport, TIOCM_RTS);
- }
+ free_irq(bsi->host_wake_irq, "tibluesleep");
clear_bit(BT_SUSPEND, &flags);
set_bit(BT_ACTIVE, &flags);
}
@@ -317,6 +213,7 @@ static struct platform_driver bluesleep_driver = {
.owner = THIS_MODULE,
},
};
+
/**
* Initializes the module.
* @return On success, 0. On error, -1, and <code>errno</code> is set
@@ -337,12 +234,6 @@ static int __init bluesleep_init(void)
flags = FLAG_RESET; /* clear all status bits */
- /* Initialize spinlock. */
- spin_lock_init(&rw_lock);
-
- /* initialize host wake tasklet */
- tasklet_init(&hostwake_task, bluesleep_hostwake_task, 0);
-
return 0;
fail:
return retval;
@@ -351,7 +242,6 @@ fail:
/**
* Cleans up the module.
*/
-
static void __exit bluesleep_exit(void)
{
if (bsi == NULL)
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 6db161f..a9a1137 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -89,6 +89,51 @@ void clk_put(struct clk *clk)
}
EXPORT_SYMBOL(clk_put);
+static void devm_clk_release(struct device *dev, void *res)
+{
+ clk_put(*(struct clk **)res);
+}
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+ struct clk **ptr, *clk;
+
+ ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ clk = clk_get(dev, id);
+ if (!IS_ERR(clk)) {
+ *ptr = clk;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return clk;
+}
+EXPORT_SYMBOL(devm_clk_get);
+
+static int devm_clk_match(struct device *dev, void *res, void *data)
+{
+ struct clk **c = res;
+ if (!c || !*c) {
+ WARN_ON(!c || !*c);
+ return 0;
+ }
+ return *c == data;
+}
+
+void devm_clk_put(struct device *dev, struct clk *clk)
+{
+ int ret;
+
+ ret = devres_destroy(dev, devm_clk_release, devm_clk_match, clk);
+
+ WARN_ON(ret);
+}
+EXPORT_SYMBOL(devm_clk_put);
+
void clkdev_add(struct clk_lookup *cl)
{
mutex_lock(&clocks_mutex);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 3acc428..629806d 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1640,9 +1640,9 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
unsigned int pmax = policy->max;
qmin = min((unsigned int)pm_qos_request(PM_QOS_CPU_FREQ_MIN),
- data->max);
+ data->user_policy.max);
qmax = max((unsigned int)pm_qos_request(PM_QOS_CPU_FREQ_MAX),
- data->min);
+ data->user_policy.min);
pr_debug("setting new policy for CPU %u: %u - %u (%u - %u) kHz\n",
policy->cpu, pmin, pmax, qmin, qmax);
@@ -1654,7 +1654,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
memcpy(&policy->cpuinfo, &data->cpuinfo,
sizeof(struct cpufreq_cpuinfo));
- if (policy->min > data->max || policy->max < data->min) {
+ if (policy->min > data->user_policy.max ||
+ policy->max < data->user_policy.min) {
ret = -EINVAL;
goto error_out;
}
@@ -1785,6 +1786,56 @@ no_policy:
}
EXPORT_SYMBOL(cpufreq_update_policy);
+/*
+ * cpufreq_set_gov - set governor for a cpu
+ * @cpu: CPU whose governor needs to be changed
+ * @target_gov: new governor to be set
+ */
+int cpufreq_set_gov(char *target_gov, unsigned int cpu)
+{
+ int ret = 0;
+ struct cpufreq_policy new_policy;
+ struct cpufreq_policy *cur_policy;
+
+ if (target_gov == NULL)
+ return -EINVAL;
+
+ /* Get current governer */
+ cur_policy = cpufreq_cpu_get(cpu);
+ if (!cur_policy)
+ return -EINVAL;
+
+ new_policy = *cur_policy;
+ if (!strncmp(cur_policy->governor->name, target_gov,
+ strlen(target_gov))) {
+ /* Target governer & current governer is same */
+ ret = -EINVAL;
+ goto err_out;
+ } else {
+ if (cpufreq_parse_governor(target_gov, &new_policy.policy,
+ &new_policy.governor)) {
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ if (lock_policy_rwsem_write(cur_policy->cpu) < 0) {
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ ret = __cpufreq_set_policy(cur_policy, &new_policy);
+
+ cur_policy->user_policy.policy = cur_policy->policy;
+ cur_policy->user_policy.governor = cur_policy->governor;
+
+ unlock_policy_rwsem_write(cur_policy->cpu);
+ }
+err_out:
+ cpufreq_cpu_put(cur_policy);
+ return ret;
+}
+EXPORT_SYMBOL(cpufreq_set_gov);
+
static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c
index 22a96ed..291cb4b 100644
--- a/drivers/crypto/tegra-aes.c
+++ b/drivers/crypto/tegra-aes.c
@@ -890,15 +890,18 @@ static int tegra_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
spin_lock_irqsave(&dd->lock, flags);
err = ablkcipher_enqueue_request(&dd->queue, req);
- bsev_busy = test_and_set_bit(FLAGS_BUSY, &dd->bsev.busy);
- bsea_busy = test_and_set_bit(FLAGS_BUSY, &dd->bsea.busy);
spin_unlock_irqrestore(&dd->lock, flags);
-
- if (!bsev_busy)
+ bsev_busy = test_and_set_bit(FLAGS_BUSY, &dd->bsev.busy);
+ if (!bsev_busy) {
queue_work(bsev_wq, &bsev_work);
+ goto finish;
+ }
+
+ bsea_busy = test_and_set_bit(FLAGS_BUSY, &dd->bsea.busy);
if (!bsea_busy)
queue_work(bsea_wq, &bsea_work);
+finish:
return err;
}
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 3a0893f..17e9c1c 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -191,6 +191,7 @@ static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0);
+ tegra_gpio_enable(offset);
return 0;
}
@@ -199,6 +200,7 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
{
tegra_gpio_set(chip, offset, value);
tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1);
+ tegra_gpio_enable(offset);
return 0;
}
@@ -213,8 +215,20 @@ static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return TEGRA_GPIO_TO_IRQ(offset);
}
+static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return 0;
+}
+
+static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ tegra_gpio_disable(offset);
+}
+
static struct gpio_chip tegra_gpio_chip = {
.label = "tegra-gpio",
+ .request = tegra_gpio_request,
+ .free = tegra_gpio_free,
.direction_input = tegra_gpio_direction_input,
.get = tegra_gpio_get,
.direction_output = tegra_gpio_direction_output,
diff --git a/drivers/gpu/ion/tegra/tegra_ion.c b/drivers/gpu/ion/tegra/tegra_ion.c
index 2252079..e929ec8 100644
--- a/drivers/gpu/ion/tegra/tegra_ion.c
+++ b/drivers/gpu/ion/tegra/tegra_ion.c
@@ -31,7 +31,7 @@
#define HEAP_FLAGS 0xFF
#if !defined(CONFIG_TEGRA_NVMAP)
-#include "mach/nvmap.h"
+#include "linux/nvmap.h"
struct nvmap_device *nvmap_dev;
#endif
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 5cd25bd..81c054e 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -155,6 +155,26 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev)
return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
}
+static void sixaxis_set_led_bt(struct hid_device *hdev)
+{
+ hid_info(hdev, "set LED BT\n");
+ /* set first LED on BT connection */
+ unsigned char led_data[] = {
+ 0x01,
+ /* rumble values */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* LED settings 0x02=LED1 .. 0x10=LED4 */
+ 0x02,
+ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED 4 */
+ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED 3 */
+ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED 2 */
+ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED 1 */
+ 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ hdev->hid_output_raw_report(hdev, led_data, sizeof(led_data),
+ HID_OUTPUT_REPORT);
+}
+
static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret;
@@ -187,8 +207,11 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
ret = sixaxis_set_operational_usb(hdev);
}
- else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
+ else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
ret = sixaxis_set_operational_bt(hdev);
+ if (ret >= 0)
+ sixaxis_set_led_bt(hdev);
+ }
else
ret = 0;
diff --git a/drivers/hwmon/tegra-tsensor.c b/drivers/hwmon/tegra-tsensor.c
index b466033..28597ef 100644
--- a/drivers/hwmon/tegra-tsensor.c
+++ b/drivers/hwmon/tegra-tsensor.c
@@ -38,7 +38,7 @@
/* macro to enable tsensor hw reset */
/* FIXME: till tsensor temperature is reliable this should be 0 */
-#define ENABLE_TSENSOR_HW_RESET 0
+#define ENABLE_TSENSOR_HW_RESET 1
/* tsensor instance used for temperature calculation */
#define TSENSOR_FUSE_REV1 8
@@ -1542,7 +1542,7 @@ static int tsensor_within_limits(struct tegra_tsensor_data *data)
static void tsensor_work_func(struct work_struct *work)
{
- struct tegra_tsensor_data *data = container_of(work,
+ struct tegra_tsensor_data *data = container_of(to_delayed_work(work),
struct tegra_tsensor_data, work);
if (!data->alert_func)
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index a4c1e0d..96916be 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -106,13 +106,26 @@
#define I2C_HEADER_10BIT_ADDR (1<<18)
#define I2C_HEADER_IE_ENABLE (1<<17)
#define I2C_HEADER_REPEAT_START (1<<16)
+#define I2C_HEADER_CONTINUE_XFER (1<<15)
#define I2C_HEADER_MASTER_ADDR_SHIFT 12
#define I2C_HEADER_SLAVE_ADDR_SHIFT 1
#define SL_ADDR1(addr) (addr & 0xff)
#define SL_ADDR2(addr) ((addr >> 8) & 0xff)
+/*
+ * msg_end_type: The bus control which need to be send at end of transfer.
+ * @MSG_END_STOP: Send stop pulse at end of transfer.
+ * @MSG_END_REPEAT_START: Send repeat start at end of transfer.
+ * @MSG_END_CONTINUE: The following on message is coming and so do not send
+ * stop or repeat start.
+ */
+enum msg_end_type {
+ MSG_END_STOP,
+ MSG_END_REPEAT_START,
+ MSG_END_CONTINUE,
+};
struct tegra_i2c_dev;
@@ -570,9 +583,12 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
}
i2c_writel(i2c_dev, status, I2C_INT_STATUS);
+ i2c_readl(i2c_dev, I2C_INT_STATUS);
- if (i2c_dev->is_dvc)
+ if (i2c_dev->is_dvc) {
dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
+ dvc_readl(i2c_dev, DVC_STATUS);
+ }
if (status & I2C_INT_PACKET_XFER_COMPLETE) {
BUG_ON(i2c_dev->msg_buf_remaining);
@@ -608,20 +624,23 @@ err:
I2C_INT_RX_FIFO_DATA_REQ | I2C_INT_TX_FIFO_OVERFLOW);
i2c_writel(i2c_dev, status, I2C_INT_STATUS);
+ i2c_readl(i2c_dev, I2C_INT_STATUS);
/* An error occured, mask dvc interrupt */
if (i2c_dev->is_dvc)
dvc_i2c_mask_irq(i2c_dev, DVC_CTRL_REG3_I2C_DONE_INTR_EN);
- if (i2c_dev->is_dvc)
+ if (i2c_dev->is_dvc) {
dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
+ dvc_readl(i2c_dev, DVC_STATUS);
+ }
complete(&i2c_dev->msg_complete);
return IRQ_HANDLED;
}
static int tegra_i2c_xfer_msg(struct tegra_i2c_bus *i2c_bus,
- struct i2c_msg *msg, int stop)
+ struct i2c_msg *msg, enum msg_end_type end_state)
{
struct tegra_i2c_dev *i2c_dev = i2c_bus->dev;
u32 int_mask;
@@ -654,8 +673,11 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_bus *i2c_bus,
i2c_writel(i2c_dev, i2c_dev->payload_size, I2C_TX_FIFO);
i2c_dev->io_header = I2C_HEADER_IE_ENABLE;
- if (!stop)
+ if (end_state == MSG_END_CONTINUE)
+ i2c_dev->io_header |= I2C_HEADER_CONTINUE_XFER;
+ else if (end_state == MSG_END_REPEAT_START)
i2c_dev->io_header |= I2C_HEADER_REPEAT_START;
+
if (msg->flags & I2C_M_TEN) {
i2c_dev->io_header |= msg->addr;
i2c_dev->io_header |= I2C_HEADER_10BIT_ADDR;
@@ -772,8 +794,14 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
tegra_i2c_clock_enable(i2c_dev);
for (i = 0; i < num; i++) {
- int stop = (i == (num - 1)) ? 1 : 0;
- ret = tegra_i2c_xfer_msg(i2c_bus, &msgs[i], stop);
+ enum msg_end_type end_type = MSG_END_STOP;
+ if (i < (num - 1)) {
+ if (msgs[i + 1].flags & I2C_M_NOSTART)
+ end_type = MSG_END_CONTINUE;
+ else
+ end_type = MSG_END_REPEAT_START;
+ }
+ ret = tegra_i2c_xfer_msg(i2c_bus, &msgs[i], end_type);
if (ret)
break;
}
diff --git a/drivers/input/touchscreen/rmi4/rmi_bus.c b/drivers/input/touchscreen/rmi4/rmi_bus.c
index 6a269df..def8a20 100644
--- a/drivers/input/touchscreen/rmi4/rmi_bus.c
+++ b/drivers/input/touchscreen/rmi4/rmi_bus.c
@@ -39,17 +39,15 @@ static int rmi_bus_match(struct device *dev, struct device_driver *driver)
rmi_dev = to_rmi_device(dev);
pdata = to_rmi_platform_data(rmi_dev);
- pr_info(" rmi_driver->driver.name = %s\n", rmi_driver->driver.name);
- pr_info(" device:rmi_device = 0x%x \n", rmi_dev);
- pr_info(" device:rmi_device:rmi_device_platform_data:driver_name = %s \n", pdata->driver_name);
- pr_info(" rmi_device:driver = 0x%x \n", rmi_dev->driver);
+ pr_info("rmi_driver->driver.name = %s\n", rmi_driver->driver.name);
+ pr_info("device:rmi_device:rmi_device_platform_data:driver_name = %s\n",
+ pdata->driver_name);
if (!strcmp(pdata->driver_name, rmi_driver->driver.name)) {
rmi_dev->driver = rmi_driver;
- pr_info(" names match, so now rmi_device:driver = 0x%x \n",rmi_dev->driver);
return 1;
}
- pr_info(" names DO NOT match, so return nothing \n");
+ pr_info("names DO NOT match, so return nothing\n");
return 0;
}
@@ -151,9 +149,9 @@ int rmi_register_phys_device(struct rmi_phys_device *phys)
dev_set_name(&rmi_dev->dev, "sensor%02d", phys_device_num++);
phys->rmi_dev = rmi_dev;
- pr_info(" registering physical device:\n");
- pr_info(" dev.init_name = \n", rmi_dev->dev.init_name);
- pr_info(" dev.bus->name = \n", rmi_dev->dev.bus->name);
+ pr_info("registering physical device:\n");
+ pr_info("dev.init_name = %s\n", rmi_dev->dev.init_name);
+ pr_info("dev.bus->name = %s\n", rmi_dev->dev.bus->name);
return device_register(&rmi_dev->dev);
}
EXPORT_SYMBOL(rmi_register_phys_device);
diff --git a/drivers/input/touchscreen/rmi4/rmi_f09.c b/drivers/input/touchscreen/rmi4/rmi_f09.c
index 0ec980d..4328d49 100644
--- a/drivers/input/touchscreen/rmi4/rmi_f09.c
+++ b/drivers/input/touchscreen/rmi4/rmi_f09.c
@@ -86,13 +86,13 @@ static ssize_t rmi_f09_HostTestEn_show(struct device *dev,
static ssize_t rmi_f09_HostTestEn_store(struct device *dev,
struct device_attribute *attr,
- char *buf, size_t count);
-
-static ssize_t rmi_f09_InternalLimits_show(struct device *dev,
- struct device_attribute *attr, char *buf);
+ const char *buf, size_t count);
static ssize_t rmi_f09_Result_Register_Count_show(struct device *dev,
struct device_attribute *attr, char *buf);
+#if defined(RMI_SYS_ATTR)
+static ssize_t rmi_f09_InternalLimits_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
static ssize_t rmi_f09_Overall_BIST_Result_show(struct device *dev,
struct device_attribute *attr, char *buf);
@@ -100,6 +100,7 @@ static ssize_t rmi_f09_Overall_BIST_Result_show(struct device *dev,
static ssize_t rmi_f09_Overall_BIST_Result_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
+#endif
static struct device_attribute attrs[] = {
__ATTR(Limit_Register_Count, RMI_RO_ATTR,
@@ -119,7 +120,6 @@ static int rmi_f09_init(struct rmi_function_container *fc)
struct rmi_fn_09_data *f09;
u8 query_base_addr;
int rc;
- int i;
int attr_count = 0;
int retval = 0;
@@ -171,8 +171,8 @@ static void rmi_f09_remove(struct rmi_function_container *fc)
{
struct rmi_fn_09_data *data = fc->data;
if (data) {
- kfree(data->query.Limit_Register_Count);
- kfree(data->query.f09_bist_query1);
+ kfree(&data->query.Limit_Register_Count);
+ kfree(&data->query.f09_bist_query1);
}
kfree(fc->data);
}
@@ -230,7 +230,7 @@ static ssize_t rmi_f09_HostTestEn_show(struct device *dev,
static ssize_t rmi_f09_HostTestEn_store(struct device *dev,
struct device_attribute *attr,
- char *buf, size_t count)
+ const char *buf, size_t count)
{
struct rmi_function_container *fc;
struct rmi_fn_09_data *data;
@@ -264,7 +264,8 @@ static ssize_t rmi_f09_HostTestEn_store(struct device *dev,
}
-static ssize_t rmi_f09_InternalLimits_show(struct device *dev,
+#if defined(RMI_SYS_ATTR)
+ ssize_t rmi_f09_InternalLimits_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -276,6 +277,7 @@ static ssize_t rmi_f09_InternalLimits_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%u\n",
data->query.InternalLimits);
}
+#endif
static ssize_t rmi_f09_Result_Register_Count_show(struct device *dev,
struct device_attribute *attr,
diff --git a/drivers/input/touchscreen/rmi4/rmi_spi.c b/drivers/input/touchscreen/rmi4/rmi_spi.c
index 41f7265..71c98bc 100644
--- a/drivers/input/touchscreen/rmi4/rmi_spi.c
+++ b/drivers/input/touchscreen/rmi4/rmi_spi.c
@@ -523,19 +523,16 @@ static int rmi_spi_v2_set_page(struct rmi_phys_device *phys, u8 page)
static int acquire_attn_irq(struct rmi_spi_data *data)
{
int retval = 0;
- pr_info("in function ____%s____ \n", __func__);
- pr_info(" irq = %d\n", data->irq);
- pr_info(" rmi_spi_hard_irq = 0x%8x\n", rmi_spi_hard_irq);
- pr_info(" rmi_spi_irq_thread = 0x%8x\n", rmi_spi_irq_thread);
- pr_info(" data->irq_flags = 0x%8x\n", data->irq_flags);
- pr_info(" dev_name(data->phys->dev) = %s\n", dev_name(data->phys->dev));
- pr_info(" data->phys = 0x%8x\n", data->phys);
+ pr_info("in function ____%s____\n", __func__);
+ pr_info("irq = %d\n", data->irq);
+ pr_info("data->irq_flags = 0x%8x\n", data->irq_flags);
+ pr_info("dev_name(data->phys->dev) = %s\n", dev_name(data->phys->dev));
retval = request_threaded_irq(data->irq, rmi_spi_hard_irq,
rmi_spi_irq_thread, data->irq_flags,
dev_name(data->phys->dev), data->phys);
- pr_info(" retval = = %d\n", retval);
+ pr_info("retval = %d\n", retval);
return retval;
}
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index c33557c..618f1bf 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -246,7 +246,7 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,
pfn = __phys_to_pfn(pa);
if (!pfn_valid(pfn)) {
dev_err(gart->dev, "Invalid page: %08x\n", pa);
- spin_lock_irqsave(&gart->pte_lock, flags);
+ spin_unlock_irqrestore(&gart->pte_lock, flags);
return -EINVAL;
}
gart_set_pte(gart, iova, GART_PTE(pfn));
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index f4d859f..bf33c030 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -734,7 +734,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain,
pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n");
}
- dev_dbg(smmu->dev, "%s is attached\n", dev_name(c->dev));
+ dev_dbg(smmu->dev, "%s is attached\n", dev_name(dev));
return 0;
err_client:
diff --git a/drivers/media/video/tegra/Kconfig b/drivers/media/video/tegra/Kconfig
index 404d771..f5aea996 100644
--- a/drivers/media/video/tegra/Kconfig
+++ b/drivers/media/video/tegra/Kconfig
@@ -27,6 +27,13 @@ config VIDEO_OV5650
This is a driver for the Omnivision OV5650 5MP camera sensor
for use with the tegra isp.
+config VIDEO_OV5640
+ tristate "OV5640 camera sensor support"
+ depends on I2C && ARCH_TEGRA
+ ---help---
+ This is a driver for the Omnivision OV5640 5MP camera sensor
+ for use with the tegra isp.
+
config VIDEO_OV14810
tristate "OV14810 camera sensor support"
depends on I2C && ARCH_TEGRA
diff --git a/drivers/media/video/tegra/Makefile b/drivers/media/video/tegra/Makefile
index 5d404e4..08b81e2 100644
--- a/drivers/media/video/tegra/Makefile
+++ b/drivers/media/video/tegra/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_TEGRA_DTV) += tegra_dtv.o
obj-$(CONFIG_TEGRA_CAMERA) += tegra_camera.o
obj-$(CONFIG_VIDEO_AR0832) += ar0832_main.o
obj-$(CONFIG_VIDEO_OV5650) += ov5650.o
+obj-$(CONFIG_VIDEO_OV5640) += ov5640.o
obj-$(CONFIG_VIDEO_OV14810) += ov14810.o
obj-$(CONFIG_VIDEO_OV9726) += ov9726.o
obj-$(CONFIG_VIDEO_OV2710) += ov2710.o
diff --git a/drivers/media/video/tegra/ad5820.c b/drivers/media/video/tegra/ad5820.c
index 19d35bc..adfda3e 100644
--- a/drivers/media/video/tegra/ad5820.c
+++ b/drivers/media/video/tegra/ad5820.c
@@ -228,4 +228,4 @@ static void __exit ad5820_exit(void)
module_init(ad5820_init);
module_exit(ad5820_exit);
-
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/tegra/ar0832_main.c b/drivers/media/video/tegra/ar0832_main.c
index 129825c..f3b56bb 100644
--- a/drivers/media/video/tegra/ar0832_main.c
+++ b/drivers/media/video/tegra/ar0832_main.c
@@ -738,7 +738,7 @@ static struct ar0832_reg mode_1920X1080_8140[] = {
{0x3178, 0x0000}, /* RESERVED_MFR_3178 */
{0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
- {0x0342, 0x103B}, /* LINE_LENGTH_PCK */
+ {0x0342, 0x1139}, /* LINE_LENGTH_PCK */
{0x0340, 0x05C4}, /* FRAME_LENGTH_LINES */
{0x0202, 0x05C4}, /* COARSE_INTEGRATION_TIME */
{0x3014, 0x0702}, /* FINE_INTEGRATION_TIME */
@@ -863,7 +863,7 @@ static struct ar0832_reg mode_1920X1080_8141[] = {
{0x3178, 0x0000}, /* RESERVED_MFR_3178 */
{0x3ED0, 0x1E24}, /* RESERVED_MFR_3ED0 */
- {0x0342, 0x103B}, /* LINE_LENGTH_PCK */
+ {0x0342, 0x1139}, /* LINE_LENGTH_PCK */
{0x0340, 0x05C4}, /* FRAME_LENGTH_LINES */
{0x0202, 0x05C4}, /* COARSE_INTEGRATION_TIME */
{0x3014, 0x0702}, /* FINE_INTEGRATION_TIME */
@@ -1977,7 +1977,7 @@ static int ar0832_focuser_set_position(struct ar0832_dev *dev,
return ret;
}
-
+#ifdef AR0832_FOCUSER_DYNAMIC_STEP_TIME
/*
* This function is not currently called as we have the hardcoded
* step time in ar0832_focuser_set_config function. If we need to
@@ -2033,6 +2033,7 @@ static u16 ar0832_get_focuser_vcm_step_time(struct ar0832_dev *dev)
return vt_pix_clk_freq_mhz;
}
+#endif
static inline
int ar0832_get_sensorid(struct ar0832_dev *dev, u16 *sensor_id)
@@ -2148,7 +2149,6 @@ static long ar0832_ioctl(struct file *file,
}
case AR0832_IOCTL_SET_SENSOR_REGION:
{
- struct ar0832_stereo_region region;
dev_dbg(&i2c_client->dev, "AR0832_IOCTL_SET_SENSOR_REGION\n");
/* Right now, it doesn't do anything */
@@ -2547,3 +2547,4 @@ static void __exit ar0832_exit(void)
module_init(ar0832_init);
module_exit(ar0832_exit);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/tegra/avp/avp.c b/drivers/media/video/tegra/avp/avp.c
index 074a42f..fc965e4 100644
--- a/drivers/media/video/tegra/avp/avp.c
+++ b/drivers/media/video/tegra/avp/avp.c
@@ -42,7 +42,7 @@
#include <mach/clk.h>
#include <mach/io.h>
#include <mach/iomap.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include <mach/legacy_irq.h>
#include <mach/hardware.h>
diff --git a/drivers/media/video/tegra/avp/avp_svc.c b/drivers/media/video/tegra/avp/avp_svc.c
index 17c8b85..1e82199 100644
--- a/drivers/media/video/tegra/avp/avp_svc.c
+++ b/drivers/media/video/tegra/avp/avp_svc.c
@@ -29,7 +29,7 @@
#include <linux/types.h>
#include <mach/clk.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
#include "../../../../video/tegra/nvmap/nvmap.h"
diff --git a/drivers/media/video/tegra/nvavp/nvavp_dev.c b/drivers/media/video/tegra/nvavp/nvavp_dev.c
index 4627c51..012f50b 100644
--- a/drivers/media/video/tegra/nvavp/nvavp_dev.c
+++ b/drivers/media/video/tegra/nvavp/nvavp_dev.c
@@ -40,9 +40,8 @@
#include <mach/io.h>
#include <mach/iomap.h>
#include <mach/legacy_irq.h>
-#include <mach/nvmap.h>
+#include <linux/nvmap.h>
-#include "../../../../video/tegra/nvmap/nvmap.h"
#include "../../../../video/tegra/host/host1x/host1x_syncpt.h"
#include "../../../../video/tegra/host/dev.h"
#include "../../../../video/tegra/host/nvhost_acm.h"
@@ -118,6 +117,7 @@ struct nvavp_info {
struct nvhost_device *nvhost_dev;
struct miscdevice misc_dev;
+ atomic_t clock_stay_on_refcount;
};
struct nvavp_clientctx {
@@ -127,7 +127,7 @@ struct nvavp_clientctx {
struct nvmap_handle_ref *gather_mem;
int num_relocs;
struct nvavp_info *nvavp;
- u32 clk_reqs;
+ int clock_stay_on;
};
static struct clk *nvavp_clk_get(struct nvavp_info *nvavp, int id)
@@ -176,7 +176,8 @@ static void nvavp_clks_disable(struct nvavp_info *nvavp)
static u32 nvavp_check_idle(struct nvavp_info *nvavp)
{
struct nv_e276_control *control = nvavp->os_control;
- return (control->put == control->get) ? 1 : 0;
+ return ((control->put == control->get)
+ && (!atomic_read(&nvavp->clock_stay_on_refcount))) ? 1 : 0;
}
static void clock_disable_handler(struct work_struct *work)
@@ -1061,15 +1062,16 @@ static int nvavp_force_clock_stay_on_ioctl(struct file *filp, unsigned int cmd,
return -EINVAL;
}
- mutex_lock(&nvavp->open_lock);
- if (clock.state) {
- if (clientctx->clk_reqs++ == 0)
- nvavp_clks_enable(nvavp);
- } else {
- if (--clientctx->clk_reqs == 0)
- nvavp_clks_disable(nvavp);
- }
- mutex_unlock(&nvavp->open_lock);
+ if (clientctx->clock_stay_on == clock.state)
+ return 0;
+
+ clientctx->clock_stay_on = clock.state;
+
+ if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED)
+ atomic_inc(&nvavp->clock_stay_on_refcount);
+ else if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_DISABLED)
+ atomic_dec(&nvavp->clock_stay_on_refcount);
+
return 0;
}
@@ -1098,6 +1100,7 @@ static int tegra_nvavp_open(struct inode *inode, struct file *filp)
clientctx->nvmap = nvavp->nvmap;
clientctx->nvavp = nvavp;
+ clientctx->clock_stay_on = NVAVP_CLOCK_STAY_ON_DISABLED;
filp->private_data = clientctx;
@@ -1125,10 +1128,8 @@ static int tegra_nvavp_release(struct inode *inode, struct file *filp)
goto out;
}
- /* if this client had any requests, drop our clk ref */
- if (clientctx->clk_reqs)
- nvavp_clks_disable(nvavp);
-
+ if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED)
+ atomic_dec(&nvavp->clock_stay_on_refcount);
if (nvavp->refcount > 0)
nvavp->refcount--;
if (!nvavp->refcount)
@@ -1187,7 +1188,8 @@ static const struct file_operations tegra_nvavp_fops = {
.unlocked_ioctl = tegra_nvavp_ioctl,
};
-static int tegra_nvavp_probe(struct nvhost_device *ndev)
+static int tegra_nvavp_probe(struct nvhost_device *ndev,
+ struct nvhost_device_id *id_table)
{
struct nvavp_info *nvavp;
int irq;
@@ -1234,17 +1236,7 @@ static int tegra_nvavp_probe(struct nvhost_device *ndev)
switch (heap_mask) {
case NVMAP_HEAP_IOVMM:
-#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000
- iovmm_addr = 0xeff00000;
-#else
iovmm_addr = 0x0ff00000;
-#endif
-
- /* Tegra3 A01 has different SMMU address */
- if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3
- && tegra_get_revision() == TEGRA_REVISION_A01) {
- iovmm_addr = 0xeff00000;
- }
nvavp->os_info.handle = nvmap_alloc_iovm(nvavp->nvmap, SZ_1M,
L1_CACHE_BYTES,
diff --git a/drivers/media/video/tegra/ov14810.c b/drivers/media/video/tegra/ov14810.c
index 2efd283..8a72cd7 100644
--- a/drivers/media/video/tegra/ov14810.c
+++ b/drivers/media/video/tegra/ov14810.c
@@ -1387,4 +1387,4 @@ static void __exit ov14810_exit(void)
module_init(ov14810_init);
module_exit(ov14810_exit);
-
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/tegra/ov2710.c b/drivers/media/video/tegra/ov2710.c
index a2e0236..5e8eaa1 100644
--- a/drivers/media/video/tegra/ov2710.c
+++ b/drivers/media/video/tegra/ov2710.c
@@ -687,4 +687,4 @@ static void __exit ov2710_exit(void)
module_init(ov2710_init);
module_exit(ov2710_exit);
-
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/tegra/ov5640.c b/drivers/media/video/tegra/ov5640.c
new file mode 100644
index 00000000..b20c036
--- /dev/null
+++ b/drivers/media/video/tegra/ov5640.c
@@ -0,0 +1,491 @@
+/*
+ * ov5640.c - ov5640 sensor driver
+ *
+ * Copyright (c) 2011 - 2012, NVIDIA, All Rights Reserved.
+ *
+ * Contributors:
+ * Abhinav Sinha <absinha@nvidia.com>
+ *
+ * Leverage soc380.c
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/**
+ * SetMode Sequence for 640x480. Phase 0. Sensor Dependent.
+ * This sequence should put sensor in streaming mode for 640x480
+ * This is usually given by the FAE or the sensor vendor.
+ */
+
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <media/ov5640.h>
+
+#include "ov5640_tables.h"
+
+/* Focuser single step & full scale transition time truth table
+ * in the format of:
+ * index mode single step transition full scale transition
+ * 0 0 0 0
+ * 1 1 50uS 51.2mS
+ * 2 1 100uS 102.3mS
+ * 3 1 200uS 204.6mS
+ * 4 1 400uS 409.2mS
+ * 5 1 800uS 818.4mS
+ * 6 1 1600uS 1637.0mS
+ * 7 1 3200uS 3274.0mS
+ * 8 0 0 0
+ * 9 2 50uS 1.1mS
+ * A 2 100uS 2.2mS
+ * B 2 200uS 4.4mS
+ * C 2 400uS 8.8mS
+ * D 2 800uS 17.6mS
+ * E 2 1600uS 35.2mS
+ * F 2 3200uS 70.4mS
+ */
+
+/* pick up the mode index setting and its settle time from the above table */
+#define OV5640_VCM_DACMODE 0x3602
+#define OV5640_TRANSITION_MODE 0x0B
+#define SETTLETIME_MS 5
+
+#define POS_LOW (0)
+#define POS_HIGH (1023)
+#define FPOS_COUNT 1024
+#define FOCAL_LENGTH (10.0f)
+#define FNUMBER (2.8f)
+
+#define SIZEOF_I2C_TRANSBUF 64
+
+struct ov5640_info {
+ int mode;
+ struct miscdevice miscdev_info;
+ struct i2c_client *i2c_client;
+ struct ov5640_platform_data *pdata;
+ struct ov5640_config focuser;
+ int af_fw_loaded;
+ struct kobject *kobj;
+ struct device *dev;
+ u8 i2c_trans_buf[SIZEOF_I2C_TRANSBUF];
+};
+
+static int ov5640_read_reg(struct i2c_client *client, u16 addr, u8 *val)
+{
+ int err;
+ struct i2c_msg msg[2];
+ unsigned char data[3];
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 2;
+ msg[0].buf = data;
+
+ /* high byte goes out first */
+ data[0] = (u8) (addr >> 8);
+ data[1] = (u8) (addr & 0xff);
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 1;
+ msg[1].buf = data + 2;
+
+ err = i2c_transfer(client->adapter, msg, 2);
+
+ if (err != 2)
+ return -EINVAL;
+
+ *val = data[2];
+
+ return 0;
+}
+
+static int ov5640_write_reg(struct i2c_client *client, u8 addr, u8 value)
+{
+ int count;
+ struct i2c_msg msg[1];
+ unsigned char data[4];
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ data[0] = addr;
+ data[1] = (u8) (addr & 0xff);
+ data[2] = value;
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 3;
+ msg[0].buf = data;
+
+ count = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+ if (count == ARRAY_SIZE(msg))
+ return 0;
+ dev_err(&client->dev,
+ "ov5840: i2c transfer failed, addr: %x, value: %02x\n",
+ addr, (u32)value);
+ return -EIO;
+}
+
+static int ov5640_write_bulk_reg(struct i2c_client *client, u8 *data, int len)
+{
+ int err;
+ struct i2c_msg msg;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = len;
+ msg.buf = data;
+
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (err == 1)
+ return 0;
+
+ dev_err(&client->dev, "ov5640: i2c transfer failed at %x\n",
+ (int)data[0] << 8 | data[1]);
+
+ return err;
+}
+
+static int ov5640_write_table(struct ov5640_info *info,
+ struct ov5640_reg table[],
+ struct ov5640_reg override_list[],
+ int num_override_regs)
+{
+ int err;
+ struct ov5640_reg *next, *n_next;
+ u8 *b_ptr = info->i2c_trans_buf;
+ unsigned int buf_filled = 0;
+ int i;
+ u16 val;
+
+ for (next = table; next->addr != OV5640_TABLE_END; next++) {
+ if (next->addr == OV5640_TABLE_WAIT_MS) {
+ msleep(next->val);
+ continue;
+ }
+
+ val = next->val;
+
+ /* When an override list is passed in, replace the reg */
+ /* value to write if the reg is in the list */
+ if (override_list) {
+ for (i = 0; i < num_override_regs; i++) {
+ if (next->addr == override_list[i].addr) {
+ val = override_list[i].val;
+ break;
+ }
+ }
+ }
+
+ if (!buf_filled) {
+ b_ptr = info->i2c_trans_buf;
+ *b_ptr++ = next->addr >> 8;
+ *b_ptr++ = next->addr & 0xff;
+ buf_filled = 2;
+ }
+ *b_ptr++ = val;
+ buf_filled++;
+
+ n_next = next + 1;
+ if (n_next->addr != OV5640_TABLE_END &&
+ n_next->addr != OV5640_TABLE_WAIT_MS &&
+ buf_filled < SIZEOF_I2C_TRANSBUF &&
+ n_next->addr == next->addr + 1) {
+ continue;
+ }
+
+ err = ov5640_write_bulk_reg(info->i2c_client,
+ info->i2c_trans_buf, buf_filled);
+ if (err)
+ return err;
+
+ buf_filled = 0;
+ }
+ return 0;
+}
+
+static int ov5640_set_mode(struct ov5640_info *info, struct ov5640_mode *mode)
+{
+ int sensor_mode;
+ int err;
+
+ dev_info(info->dev, "%s: xres %u yres %u\n",
+ __func__, mode->xr