aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 18:27:22 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 18:27:22 -0500
commitbab588fcfb6335c767d811a8955979f5440328e0 (patch)
tree2a862ddf47a82be885a8e7945a17cc3ff7a658b9
parent3298a3511f1e73255a8dc023efd909e569eea037 (diff)
parent9cb0d1babfcb1b4ac248c09425f7d5de1e771133 (diff)
Merge tag 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC-specific updates from Arnd Bergmann: "This is a larger set of new functionality for the existing SoC families, including: - vt8500 gains support for new CPU cores, notably the Cortex-A9 based wm8850 - prima2 gains support for the "marco" SoC family, its SMP based cousin - tegra gains support for the new Tegra4 (Tegra114) family - socfpga now supports a newer version of the hardware including SMP - i.mx31 and bcm2835 are now using DT probing for their clocks - lots of updates for sh-mobile - OMAP updates for clocks, power management and USB - i.mx6q and tegra now support cpuidle - kirkwood now supports PCIe hot plugging - tegra clock support is updated - tegra USB PHY probing gets implemented diffently" * tag 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (148 commits) ARM: prima2: remove duplicate v7_invalidate_l1 ARM: shmobile: r8a7779: Correct TMU clock support again ARM: prima2: fix __init section for cpu hotplug ARM: OMAP: Consolidate OMAP USB-HS platform data (part 3/3) ARM: OMAP: Consolidate OMAP USB-HS platform data (part 1/3) arm: socfpga: Add SMP support for actual socfpga harware arm: Add v7_invalidate_l1 to cache-v7.S arm: socfpga: Add entries to enable make dtbs socfpga arm: socfpga: Add new device tree source for actual socfpga HW ARM: tegra: sort Kconfig selects for Tegra114 ARM: tegra: enable ARCH_REQUIRE_GPIOLIB for Tegra114 ARM: tegra: Fix build error w/ ARCH_TEGRA_114_SOC w/o ARCH_TEGRA_3x_SOC ARM: tegra: Fix build error for gic update ARM: tegra: remove empty tegra_smp_init_cpus() ARM: shmobile: Register ARM architected timer ARM: MARCO: fix the build issue due to gic-vic-to-irqchip move ARM: shmobile: r8a7779: Correct TMU clock support ARM: mxs_defconfig: Select CONFIG_DEVTMPFS_MOUNT ARM: mxs: decrease mxs_clockevent_device.min_delta_ns to 2 clock cycles ARM: mxs: use apbx bus clock to drive the timers on timrotv2 ...
-rw-r--r--Documentation/devicetree/bindings/arm/altera/socfpga-system.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/sirf.txt10
-rw-r--r--Documentation/devicetree/bindings/arm/vt8500.txt8
-rw-r--r--Documentation/devicetree/bindings/clock/imx31-clock.txt91
-rw-r--r--Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt205
-rw-r--r--Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt262
-rw-r--r--Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt3
-rw-r--r--Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt17
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/Kconfig.debug45
-rw-r--r--arch/arm/boot/dts/Makefile10
-rw-r--r--arch/arm/boot/dts/emev2.dtsi7
-rw-r--r--arch/arm/boot/dts/imx31.dtsi17
-rw-r--r--arch/arm/boot/dts/marco-evb.dts54
-rw-r--r--arch/arm/boot/dts/marco.dtsi756
-rw-r--r--arch/arm/boot/dts/sh73a0-reference.dtsi24
-rw-r--r--arch/arm/boot/dts/sh73a0.dtsi100
-rw-r--r--arch/arm/boot/dts/socfpga.dtsi22
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5.dts34
-rw-r--r--arch/arm/boot/dts/socfpga_vt.dts64
-rw-r--r--arch/arm/boot/dts/tegra114-dalmore.dts21
-rw-r--r--arch/arm/boot/dts/tegra114-pluto.dts21
-rw-r--r--arch/arm/boot/dts/tegra114.dtsi153
-rw-r--r--arch/arm/boot/dts/tegra20-harmony.dts4
-rw-r--r--arch/arm/boot/dts/tegra20-paz00.dts6
-rw-r--r--arch/arm/boot/dts/tegra20-seaboard.dts4
-rw-r--r--arch/arm/boot/dts/tegra20-trimslice.dts4
-rw-r--r--arch/arm/boot/dts/tegra20-ventana.dts4
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi96
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi91
-rw-r--r--arch/arm/boot/dts/wm8850-w70v2.dts47
-rw-r--r--arch/arm/boot/dts/wm8850.dtsi224
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig8
-rw-r--r--arch/arm/configs/kirkwood_defconfig1
-rw-r--r--arch/arm/configs/mxs_defconfig64
-rw-r--r--arch/arm/configs/prima2_defconfig3
-rw-r--r--arch/arm/include/asm/smp_scu.h17
-rw-r--r--arch/arm/include/debug/imx-uart.h88
-rw-r--r--arch/arm/include/debug/imx.S29
-rw-r--r--arch/arm/mach-bcm2835/bcm2835.c28
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c9
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c9
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c9
-rw-r--r--arch/arm/mach-davinci/clock.c39
-rw-r--r--arch/arm/mach-davinci/clock.h3
-rw-r--r--arch/arm/mach-davinci/da850.c17
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c16
-rw-r--r--arch/arm/mach-davinci/include/mach/clock.h3
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h4
-rw-r--r--arch/arm/mach-davinci/include/mach/psc.h3
-rw-r--r--arch/arm/mach-davinci/psc.c29
-rw-r--r--arch/arm/mach-imx/Makefile6
-rw-r--r--arch/arm/mach-imx/clk-imx27.c7
-rw-r--r--arch/arm/mach-imx/clk-imx31.c15
-rw-r--r--arch/arm/mach-imx/clk-imx35.c4
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c12
-rw-r--r--arch/arm/mach-imx/common.h3
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6q.c95
-rw-r--r--arch/arm/mach-imx/cpuidle.h5
-rw-r--r--arch/arm/mach-imx/gpc.c5
-rw-r--r--arch/arm/mach-imx/headsmp.S47
-rw-r--r--arch/arm/mach-imx/imx31-dt.c17
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c17
-rw-r--r--arch/arm/mach-imx/platsmp.c10
-rw-r--r--arch/arm/mach-imx/time.c3
-rw-r--r--arch/arm/mach-kirkwood/Makefile1
-rw-r--r--arch/arm/mach-kirkwood/board-dt.c2
-rw-r--r--arch/arm/mach-kirkwood/common.c23
-rw-r--r--arch/arm/mach-kirkwood/common.h1
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h3
-rw-r--r--arch/arm/mach-kirkwood/pcie.c10
-rw-r--r--arch/arm/mach-mxs/timer.c12
-rw-r--r--arch/arm/mach-omap2/am35xx-emac.c2
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c2
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c2
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c2
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c2
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c2
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c2
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c4
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c2
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c2
-rw-r--r--arch/arm/mach-omap2/board-overo.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom.c2
-rw-r--r--arch/arm/mach-omap2/cclock2420_data.c16
-rw-r--r--arch/arm/mach-omap2/cclock2430_data.c16
-rw-r--r--arch/arm/mach-omap2/cclock44xx_data.c578
-rw-r--r--arch/arm/mach-omap2/clockdomain.c569
-rw-r--r--arch/arm/mach-omap2/clockdomain.h17
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c33
-rw-r--r--arch/arm/mach-omap2/cm3xxx.c14
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c2
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c79
-rw-r--r--arch/arm/mach-omap2/devices.c25
-rw-r--r--arch/arm/mach-omap2/display.c2
-rw-r--r--arch/arm/mach-omap2/dma.c2
-rw-r--r--arch/arm/mach-omap2/drm.c3
-rw-r--r--arch/arm/mach-omap2/gpio.c3
-rw-r--r--arch/arm/mach-omap2/gpmc.c2
-rw-r--r--arch/arm/mach-omap2/hdq1w.c2
-rw-r--r--arch/arm/mach-omap2/hsmmc.c2
-rw-r--r--arch/arm/mach-omap2/hwspinlock.c3
-rw-r--r--arch/arm/mach-omap2/i2c.c3
-rw-r--r--arch/arm/mach-omap2/mcbsp.c2
-rw-r--r--arch/arm/mach-omap2/msdi.c2
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c3
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c44
-rw-r--r--arch/arm/mach-omap2/omap-smp.c2
-rw-r--r--arch/arm/mach-omap2/omap44xx.h1
-rw-r--r--arch/arm/mach-omap2/omap_device.c537
-rw-r--r--arch/arm/mach-omap2/omap_device.h79
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h9
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c7
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c99
-rw-r--r--arch/arm/mach-omap2/pm-debug.c6
-rw-r--r--arch/arm/mach-omap2/pm.c69
-rw-r--r--arch/arm/mach-omap2/pm.h1
-rw-r--r--arch/arm/mach-omap2/pm24xx.c43
-rw-r--r--arch/arm/mach-omap2/pmu.c3
-rw-r--r--arch/arm/mach-omap2/powerdomain.c232
-rw-r--r--arch/arm/mach-omap2/powerdomain.h52
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c4
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_data.c9
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c44
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c3
-rw-r--r--arch/arm/mach-omap2/serial.c3
-rw-r--r--arch/arm/mach-omap2/sr_device.c3
-rw-r--r--arch/arm/mach-omap2/timer.c3
-rw-r--r--arch/arm/mach-omap2/usb-host.c41
-rw-r--r--arch/arm/mach-omap2/usb-musb.c2
-rw-r--r--arch/arm/mach-omap2/usb.h20
-rw-r--r--arch/arm/mach-omap2/wd_timer.c3
-rw-r--r--arch/arm/mach-prima2/Kconfig10
-rw-r--r--arch/arm/mach-prima2/Makefile5
-rw-r--r--arch/arm/mach-prima2/common.c33
-rw-r--r--arch/arm/mach-prima2/common.h15
-rw-r--r--arch/arm/mach-prima2/headsmp.S40
-rw-r--r--arch/arm/mach-prima2/hotplug.c41
-rw-r--r--arch/arm/mach-prima2/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-prima2/include/mach/uart.h6
-rw-r--r--arch/arm/mach-prima2/include/mach/uncompress.h3
-rw-r--r--arch/arm/mach-prima2/irq.c16
-rw-r--r--arch/arm/mach-prima2/l2x0.c29
-rw-r--r--arch/arm/mach-prima2/platsmp.c157
-rw-r--r--arch/arm/mach-prima2/rstc.c45
-rw-r--r--arch/arm/mach-prima2/rtciobrg.c1
-rw-r--r--arch/arm/mach-prima2/timer-marco.c316
-rw-r--r--arch/arm/mach-prima2/timer-prima2.c (renamed from arch/arm/mach-prima2/timer.c)6
-rw-r--r--arch/arm/mach-shmobile/Makefile3
-rw-r--r--arch/arm/mach-shmobile/board-armadillo800eva.c2
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c2
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c6
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7779.c1
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c9
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c35
-rw-r--r--arch/arm/mach-shmobile/headsmp-sh73a0.S50
-rw-r--r--arch/arm/mach-shmobile/headsmp.S48
-rw-r--r--arch/arm/mach-shmobile/hotplug.c6
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h9
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c16
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7740.c22
-rw-r--r--arch/arm/mach-shmobile/pm-sh73a0.c32
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c95
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c18
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c62
-rw-r--r--arch/arm/mach-shmobile/sleep-sh7372.S12
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c68
-rw-r--r--arch/arm/mach-shmobile/timer.c3
-rw-r--r--arch/arm/mach-socfpga/core.h4
-rw-r--r--arch/arm/mach-socfpga/headsmp.S16
-rw-r--r--arch/arm/mach-socfpga/platsmp.c17
-rw-r--r--arch/arm/mach-socfpga/socfpga.c7
-rw-r--r--arch/arm/mach-tegra/Kconfig15
-rw-r--r--arch/arm/mach-tegra/Makefile9
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra114.c46
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra20.c60
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra30.c62
-rw-r--r--arch/arm/mach-tegra/board.h2
-rw-r--r--arch/arm/mach-tegra/clock.c166
-rw-r--r--arch/arm/mach-tegra/clock.h153
-rw-r--r--arch/arm/mach-tegra/common.c69
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c2
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra114.c61
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra20.c197
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra30.c2
-rw-r--r--arch/arm/mach-tegra/cpuidle.c3
-rw-r--r--arch/arm/mach-tegra/cpuidle.h6
-rw-r--r--arch/arm/mach-tegra/flowctrl.c38
-rw-r--r--arch/arm/mach-tegra/flowctrl.h4
-rw-r--r--arch/arm/mach-tegra/fuse.c8
-rw-r--r--arch/arm/mach-tegra/fuse.h1
-rw-r--r--arch/arm/mach-tegra/headsmp.S43
-rw-r--r--arch/arm/mach-tegra/hotplug.c2
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h44
-rw-r--r--arch/arm/mach-tegra/iomap.h9
-rw-r--r--arch/arm/mach-tegra/irq.c15
-rw-r--r--arch/arm/mach-tegra/irq.h22
-rw-r--r--arch/arm/mach-tegra/pcie.c2
-rw-r--r--arch/arm/mach-tegra/platsmp.c25
-rw-r--r--arch/arm/mach-tegra/pm.c5
-rw-r--r--arch/arm/mach-tegra/powergate.c2
-rw-r--r--arch/arm/mach-tegra/sleep-tegra20.S200
-rw-r--r--arch/arm/mach-tegra/sleep.S19
-rw-r--r--arch/arm/mach-tegra/sleep.h26
-rw-r--r--arch/arm/mach-tegra/tegra20_clocks.c1623
-rw-r--r--arch/arm/mach-tegra/tegra20_clocks.h42
-rw-r--r--arch/arm/mach-tegra/tegra20_clocks_data.c1143
-rw-r--r--arch/arm/mach-tegra/tegra30_clocks.c2506
-rw-r--r--arch/arm/mach-tegra/tegra30_clocks.h54
-rw-r--r--arch/arm/mach-tegra/tegra30_clocks_data.c1425
-rw-r--r--arch/arm/mach-vt8500/Kconfig16
-rw-r--r--arch/arm/mach-vt8500/vt8500.c2
-rw-r--r--arch/arm/mm/cache-v7.S46
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/clk-bcm2835.c9
-rw-r--r--drivers/clk/mxs/clk-imx28.c2
-rw-r--r--drivers/clk/tegra/Makefile11
-rw-r--r--drivers/clk/tegra/clk-audio-sync.c87
-rw-r--r--drivers/clk/tegra/clk-divider.c187
-rw-r--r--drivers/clk/tegra/clk-periph-gate.c179
-rw-r--r--drivers/clk/tegra/clk-periph.c218
-rw-r--r--drivers/clk/tegra/clk-pll-out.c123
-rw-r--r--drivers/clk/tegra/clk-pll.c648
-rw-r--r--drivers/clk/tegra/clk-super.c154
-rw-r--r--drivers/clk/tegra/clk-tegra20.c1349
-rw-r--r--drivers/clk/tegra/clk-tegra30.c1987
-rw-r--r--drivers/clk/tegra/clk.c85
-rw-r--r--drivers/clk/tegra/clk.h502
-rw-r--r--drivers/cpuidle/Kconfig6
-rw-r--r--drivers/cpuidle/Makefile1
-rw-r--r--drivers/cpuidle/cpuidle-kirkwood.c (renamed from arch/arm/mach-kirkwood/cpuidle.c)45
-rw-r--r--drivers/dma/tegra20-apb-dma.c2
-rw-r--r--drivers/gpu/drm/tegra/dc.c3
-rw-r--r--drivers/gpu/drm/tegra/drm.c1
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c3
-rw-r--r--drivers/i2c/busses/i2c-tegra.c3
-rw-r--r--drivers/input/keyboard/tegra-kbc.c2
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/spi/spi-tegra20-sflash.c4
-rw-r--r--drivers/spi/spi-tegra20-slink.c4
-rw-r--r--drivers/staging/nvec/TODO4
-rw-r--r--drivers/staging/nvec/nvec.c5
-rw-r--r--drivers/usb/host/ehci-tegra.c97
-rw-r--r--drivers/usb/phy/tegra_usb_phy.c132
-rw-r--r--include/linux/clk/tegra.h (renamed from arch/arm/mach-tegra/tegra_cpu_car.h)13
-rw-r--r--include/linux/platform_data/usb-omap.h8
-rw-r--r--include/linux/tegra-soc.h22
-rw-r--r--include/linux/usb/tegra_usb_phy.h16
-rw-r--r--sound/soc/tegra/tegra30_ahub.c16
255 files changed, 11516 insertions, 9687 deletions
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
index 07c65e3cdcbe..f4d04a067282 100644
--- a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
+++ b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
@@ -3,9 +3,11 @@ Altera SOCFPGA System Manager
3Required properties: 3Required properties:
4- compatible : "altr,sys-mgr" 4- compatible : "altr,sys-mgr"
5- reg : Should contain 1 register ranges(address and length) 5- reg : Should contain 1 register ranges(address and length)
6- cpu1-start-addr : CPU1 start address in hex.
6 7
7Example: 8Example:
8 sysmgr@ffd08000 { 9 sysmgr@ffd08000 {
9 compatible = "altr,sys-mgr"; 10 compatible = "altr,sys-mgr";
10 reg = <0xffd08000 0x1000>; 11 reg = <0xffd08000 0x1000>;
12 cpu1-start-addr = <0xffd080c4>;
11 }; 13 };
diff --git a/Documentation/devicetree/bindings/arm/sirf.txt b/Documentation/devicetree/bindings/arm/sirf.txt
index 1881e1c6dda5..c6ba6d3c747f 100644
--- a/Documentation/devicetree/bindings/arm/sirf.txt
+++ b/Documentation/devicetree/bindings/arm/sirf.txt
@@ -1,3 +1,9 @@
1prima2 "cb" evaluation board 1CSR SiRFprimaII and SiRFmarco device tree bindings.
2========================================
3
2Required root node properties: 4Required root node properties:
3 - compatible = "sirf,prima2-cb", "sirf,prima2"; 5 - compatible:
6 - "sirf,prima2-cb" : prima2 "cb" evaluation board
7 - "sirf,marco-cb" : marco "cb" evaluation board
8 - "sirf,prima2" : prima2 device based board
9 - "sirf,marco" : marco device based board
diff --git a/Documentation/devicetree/bindings/arm/vt8500.txt b/Documentation/devicetree/bindings/arm/vt8500.txt
index d657832c6819..87dc1ddf4770 100644
--- a/Documentation/devicetree/bindings/arm/vt8500.txt
+++ b/Documentation/devicetree/bindings/arm/vt8500.txt
@@ -12,3 +12,11 @@ compatible = "wm,wm8505";
12Boards with the Wondermedia WM8650 SoC shall have the following properties: 12Boards with the Wondermedia WM8650 SoC shall have the following properties:
13Required root node property: 13Required root node property:
14compatible = "wm,wm8650"; 14compatible = "wm,wm8650";
15
16Boards with the Wondermedia WM8750 SoC shall have the following properties:
17Required root node property:
18compatible = "wm,wm8750";
19
20Boards with the Wondermedia WM8850 SoC shall have the following properties:
21Required root node property:
22compatible = "wm,wm8850";
diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.txt b/Documentation/devicetree/bindings/clock/imx31-clock.txt
new file mode 100644
index 000000000000..19df842c694f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx31-clock.txt
@@ -0,0 +1,91 @@
1* Clock bindings for Freescale i.MX31
2
3Required properties:
4- compatible: Should be "fsl,imx31-ccm"
5- reg: Address and length of the register set
6- interrupts: Should contain CCM interrupt
7- #clock-cells: Should be <1>
8
9The clock consumer should specify the desired clock by having the clock
10ID in its "clocks" phandle cell. The following is a full list of i.MX31
11clocks and IDs.
12
13 Clock ID
14 -----------------------
15 dummy 0
16 ckih 1
17 ckil 2
18 mpll 3
19 spll 4
20 upll 5
21 mcu_main 6
22 hsp 7
23 ahb 8
24 nfc 9
25 ipg 10
26 per_div 11
27 per 12
28 csi_sel 13
29 fir_sel 14
30 csi_div 15
31 usb_div_pre 16
32 usb_div_post 17
33 fir_div_pre 18
34 fir_div_post 19
35 sdhc1_gate 20
36 sdhc2_gate 21
37 gpt_gate 22
38 epit1_gate 23
39 epit2_gate 24
40 iim_gate 25
41 ata_gate 26
42 sdma_gate 27
43 cspi3_gate 28
44 rng_gate 29
45 uart1_gate 30
46 uart2_gate 31
47 ssi1_gate 32
48 i2c1_gate 33
49 i2c2_gate 34
50 i2c3_gate 35
51 hantro_gate 36
52 mstick1_gate 37
53 mstick2_gate 38
54 csi_gate 39
55 rtc_gate 40
56 wdog_gate 41
57 pwm_gate 42
58 sim_gate 43
59 ect_gate 44
60 usb_gate 45
61 kpp_gate 46
62 ipu_gate 47
63 uart3_gate 48
64 uart4_gate 49
65 uart5_gate 50
66 owire_gate 51
67 ssi2_gate 52
68 cspi1_gate 53
69 cspi2_gate 54
70 gacc_gate 55
71 emi_gate 56
72 rtic_gate 57
73 firi_gate 58
74
75Examples:
76
77clks: ccm@53f80000{
78 compatible = "fsl,imx31-ccm";
79 reg = <0x53f80000 0x4000>;
80 interrupts = <0 31 0x04 0 53 0x04>;
81 #clock-cells = <1>;
82};
83
84uart1: serial@43f90000 {
85 compatible = "fsl,imx31-uart", "fsl,imx21-uart";
86 reg = <0x43f90000 0x4000>;
87 interrupts = <45>;
88 clocks = <&clks 10>, <&clks 30>;
89 clock-names = "ipg", "per";
90 status = "disabled";
91};
diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt
new file mode 100644
index 000000000000..0921fac73528
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt
@@ -0,0 +1,205 @@
1NVIDIA Tegra20 Clock And Reset Controller
2
3This binding uses the common clock binding:
4Documentation/devicetree/bindings/clock/clock-bindings.txt
5
6The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
7for muxing and gating Tegra's clocks, and setting their rates.
8
9Required properties :
10- compatible : Should be "nvidia,tegra20-car"
11- reg : Should contain CAR registers location and length
12- clocks : Should contain phandle and clock specifiers for two clocks:
13 the 32 KHz "32k_in", and the board-specific oscillator "osc".
14- #clock-cells : Should be 1.
15 In clock consumers, this cell represents the clock ID exposed by the CAR.
16
17 The first 96 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
18 registers. These IDs often match those in the CAR's RST_DEVICES registers,
19 but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
20 this case, those clocks are assigned IDs above 95 in order to highlight
21 this issue. Implementations that interpret these clock IDs as bit values
22 within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
23 explicitly handle these special cases.
24
25 The balance of the clocks controlled by the CAR are assigned IDs of 96 and
26 above.
27
28 0 cpu
29 1 unassigned
30 2 unassigned
31 3 ac97
32 4 rtc
33 5 tmr
34 6 uart1
35 7 unassigned (register bit affects uart2 and vfir)
36 8 gpio
37 9 sdmmc2
38 10 unassigned (register bit affects spdif_in and spdif_out)
39 11 i2s1
40 12 i2c1
41 13 ndflash
42 14 sdmmc1
43 15 sdmmc4
44 16 twc
45 17 pwm
46 18 i2s2
47 19 epp
48 20 unassigned (register bit affects vi and vi_sensor)
49 21 2d
50 22 usbd
51 23 isp
52 24 3d
53 25 ide
54 26 disp2
55 27 disp1
56 28 host1x
57 29 vcp
58 30 unassigned
59 31 cache2
60
61 32 mem
62 33 ahbdma
63 34 apbdma
64 35 unassigned
65 36 kbc
66 37 stat_mon
67 38 pmc
68 39 fuse
69 40 kfuse
70 41 sbc1
71 42 snor
72 43 spi1
73 44 sbc2
74 45 xio
75 46 sbc3
76 47 dvc
77 48 dsi
78 49 unassigned (register bit affects tvo and cve)
79 50 mipi
80 51 hdmi
81 52 csi
82 53 tvdac
83 54 i2c2
84 55 uart3
85 56 unassigned
86 57 emc
87 58 usb2
88 59 usb3
89 60 mpe
90 61 vde
91 62 bsea
92 63 bsev
93
94 64 speedo
95 65 uart4
96 66 uart5
97 67 i2c3
98 68 sbc4
99 69 sdmmc3
100 70 pcie
101 71 owr
102 72 afi
103 73 csite
104 74 unassigned
105 75 avpucq
106 76 la
107 77 unassigned
108 78 unassigned
109 79 unassigned
110 80 unassigned
111 81 unassigned
112 82 unassigned
113 83 unassigned
114 84 irama
115 85 iramb
116 86 iramc
117 87 iramd
118 88 cram2
119 89 audio_2x a/k/a audio_2x_sync_clk
120 90 clk_d
121 91 unassigned
122 92 sus
123 93 cdev1
124 94 cdev2
125 95 unassigned
126
127 96 uart2
128 97 vfir
129 98 spdif_in
130 99 spdif_out
131 100 vi
132 101 vi_sensor
133 102 tvo
134 103 cve
135 104 osc
136 105 clk_32k a/k/a clk_s
137 106 clk_m
138 107 sclk
139 108 cclk
140 109 hclk
141 110 pclk
142 111 blink
143 112 pll_a
144 113 pll_a_out0
145 114 pll_c
146 115 pll_c_out1
147 116 pll_d
148 117 pll_d_out0
149 118 pll_e
150 119 pll_m
151 120 pll_m_out1
152 121 pll_p
153 122 pll_p_out1
154 123 pll_p_out2
155 124 pll_p_out3
156 125 pll_p_out4
157 126 pll_s
158 127 pll_u
159 128 pll_x
160 129 cop a/k/a avp
161 130 audio a/k/a audio_sync_clk
162 131 pll_ref
163 132 twd
164
165Example SoC include file:
166
167/ {
168 tegra_car: clock {
169 compatible = "nvidia,tegra20-car";
170 reg = <0x60006000 0x1000>;
171 #clock-cells = <1>;
172 };
173
174 usb@c5004000 {
175 clocks = <&tegra_car 58>; /* usb2 */
176 };
177};
178
179Example board file:
180
181/ {
182 clocks {
183 compatible = "simple-bus";
184 #address-cells = <1>;
185 #size-cells = <0>;
186
187 osc: clock@0 {
188 compatible = "fixed-clock";
189 reg = <0>;
190 #clock-cells = <0>;
191 clock-frequency = <12000000>;
192 };
193
194 clk_32k: clock@1 {
195 compatible = "fixed-clock";
196 reg = <1>;
197 #clock-cells = <0>;
198 clock-frequency = <32768>;
199 };
200 };
201
202 &tegra_car {
203 clocks = <&clk_32k> <&osc>;
204 };
205};
diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt
new file mode 100644
index 000000000000..f3da3be5fcad
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt
@@ -0,0 +1,262 @@
1NVIDIA Tegra30 Clock And Reset Controller
2
3This binding uses the common clock binding:
4Documentation/devicetree/bindings/clock/clock-bindings.txt
5
6The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
7for muxing and gating Tegra's clocks, and setting their rates.
8
9Required properties :
10- compatible : Should be "nvidia,tegra30-car"
11- reg : Should contain CAR registers location and length
12- clocks : Should contain phandle and clock specifiers for two clocks:
13 the 32 KHz "32k_in", and the board-specific oscillator "osc".
14- #clock-cells : Should be 1.
15 In clock consumers, this cell represents the clock ID exposed by the CAR.
16
17 The first 130 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
18 registers. These IDs often match those in the CAR's RST_DEVICES registers,
19 but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
20 this case, those clocks are assigned IDs above 160 in order to highlight
21 this issue. Implementations that interpret these clock IDs as bit values
22 within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
23 explicitly handle these special cases.
24
25 The balance of the clocks controlled by the CAR are assigned IDs of 160 and
26 above.
27
28 0 cpu
29 1 unassigned
30 2 unassigned
31 3 unassigned
32 4 rtc
33 5 timer
34 6 uarta
35 7 unassigned (register bit affects uartb and vfir)
36 8 gpio
37 9 sdmmc2
38 10 unassigned (register bit affects spdif_in and spdif_out)
39 11 i2s1
40 12 i2c1
41 13 ndflash
42 14 sdmmc1
43 15 sdmmc4
44 16 unassigned
45 17 pwm
46 18 i2s2
47 19 epp
48 20 unassigned (register bit affects vi and vi_sensor)
49 21 2d
50 22 usbd
51 23 isp
52 24 3d
53 25 unassigned
54 26 disp2
55 27 disp1
56 28 host1x
57 29 vcp
58 30 i2s0
59 31 cop_cache
60
61 32 mc
62 33 ahbdma
63 34 apbdma
64 35 unassigned
65 36 kbc
66 37 statmon
67 38 pmc
68 39 unassigned (register bit affects fuse and fuse_burn)
69 40 kfuse
70 41 sbc1
71 42 nor
72 43 unassigned
73 44 sbc2
74 45 unassigned
75 46 sbc3
76 47 i2c5
77 48 dsia
78 49 unassigned (register bit affects cve and tvo)
79 50 mipi
80 51 hdmi
81 52 csi
82 53 tvdac
83 54 i2c2
84 55 uartc
85 56 unassigned
86 57 emc
87 58 usb2
88 59 usb3
89 60 mpe
90 61 vde
91 62 bsea
92 63 bsev
93
94 64 speedo
95 65 uartd
96 66 uarte
97 67 i2c3
98 68 sbc4
99 69 sdmmc3
100 70 pcie
101 71 owr
102 72 afi
103 73 csite
104 74 pciex
105 75 avpucq
106 76 la
107 77 unassigned
108 78 unassigned
109 79 dtv
110 80 ndspeed
111 81 i2cslow
112 82 dsib
113 83 unassigned
114 84 irama
115 85 iramb
116 86 iramc
117 87 iramd
118 88 cram2
119 89 unassigned
120 90 audio_2x a/k/a audio_2x_sync_clk
121 91 unassigned
122 92 csus
123 93 cdev2
124 94 cdev1
125 95 unassigned
126
127 96 cpu_g
128 97 cpu_lp
129 98 3d2
130 99 mselect
131 100 tsensor
132 101 i2s3
133 102 i2s4
134 103 i2c4
135 104 sbc5
136 105 sbc6
137 106 d_audio
138 107 apbif
139 108 dam0
140 109 dam1
141 110 dam2
142 111 hda2codec_2x
143 112 atomics
144 113 audio0_2x
145 114 audio1_2x
146 115 audio2_2x
147 116 audio3_2x
148 117 audio4_2x
149 118 audio5_2x
150 119 actmon
151 120 extern1
152 121 extern2
153 122 extern3
154 123 sata_oob
155 124 sata
156 125 hda
157 127 se
158 128 hda2hdmi
159 129 sata_cold
160
161 160 uartb
162 161 vfir
163 162 spdif_in
164 163 spdif_out
165 164 vi
166 165 vi_sensor
167 166 fuse
168 167 fuse_burn
169 168 cve
170 169 tvo
171
172 170 clk_32k
173 171 clk_m
174 172 clk_m_div2
175 173 clk_m_div4
176 174 pll_ref
177 175 pll_c
178 176 pll_c_out1
179 177 pll_m
180 178 pll_m_out1
181 179 pll_p
182 180 pll_p_out1
183 181 pll_p_out2
184 182 pll_p_out3
185 183 pll_p_out4
186 184 pll_a
187 185 pll_a_out0
188 186 pll_d
189 187 pll_d_out0
190 188 pll_d2
191 189 pll_d2_out0
192 190 pll_u
193 191 pll_x
194 192 pll_x_out0
195 193 pll_e
196 194 spdif_in_sync
197 195 i2s0_sync
198 196 i2s1_sync
199 197 i2s2_sync
200 198 i2s3_sync
201 199 i2s4_sync
202 200 vimclk
203 201 audio0
204 202 audio1
205 203 audio2
206 204 audio3
207 205 audio4
208 206 audio5
209 207 clk_out_1 (extern1)
210 208 clk_out_2 (extern2)
211 209 clk_out_3 (extern3)
212 210 sclk
213 211 blink
214 212 cclk_g
215 213 cclk_lp
216 214 twd
217 215 cml0
218 216 cml1
219 217 hclk
220 218 pclk
221
222Example SoC include file:
223
224/ {
225 tegra_car: clock {
226 compatible = "nvidia,tegra30-car";
227 reg = <0x60006000 0x1000>;
228 #clock-cells = <1>;
229 };
230
231 usb@c5004000 {
232 clocks = <&tegra_car 58>; /* usb2 */
233 };
234};
235
236Example board file:
237
238/ {
239 clocks {
240 compatible = "simple-bus";
241 #address-cells = <1>;
242 #size-cells = <0>;
243
244 osc: clock@0 {
245 compatible = "fixed-clock";
246 reg = <0>;
247 #clock-cells = <0>;
248 clock-frequency = <12000000>;
249 };
250
251 clk_32k: clock@1 {
252 compatible = "fixed-clock";
253 reg = <1>;
254 #clock-cells = <0>;
255 clock-frequency = <32768>;
256 };
257 };
258
259 &tegra_car {
260 clocks = <&clk_32k> <&osc>;
261 };
262};
diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt
index e9b005dc7625..34c952883276 100644
--- a/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt
+++ b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt
@@ -11,6 +11,7 @@ Required properties :
11 - phy_type : Should be one of "ulpi" or "utmi". 11 - phy_type : Should be one of "ulpi" or "utmi".
12 - nvidia,vbus-gpio : If present, specifies a gpio that needs to be 12 - nvidia,vbus-gpio : If present, specifies a gpio that needs to be
13 activated for the bus to be powered. 13 activated for the bus to be powered.
14 - nvidia,phy : phandle of the PHY instance, the controller is connected to.
14 15
15Required properties for phy_type == ulpi: 16Required properties for phy_type == ulpi:
16 - nvidia,phy-reset-gpio : The GPIO used to reset the PHY. 17 - nvidia,phy-reset-gpio : The GPIO used to reset the PHY.
@@ -27,3 +28,5 @@ Optional properties:
27 registers are accessed through the APB_MISC base address instead of 28 registers are accessed through the APB_MISC base address instead of
28 the USB controller. Since this is a legacy issue it probably does not 29 the USB controller. Since this is a legacy issue it probably does not
29 warrant a compatible string of its own. 30 warrant a compatible string of its own.
31 - nvidia,needs-double-reset : boolean is to be set for some of the Tegra2
32 USB ports, which need reset twice due to hardware issues.
diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt b/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt
new file mode 100644
index 000000000000..6bdaba2f0aa1
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt
@@ -0,0 +1,17 @@
1Tegra SOC USB PHY
2
3The device node for Tegra SOC USB PHY:
4
5Required properties :
6 - compatible : Should be "nvidia,tegra20-usb-phy".
7 - reg : Address and length of the register set for the USB PHY interface.
8 - phy_type : Should be one of "ulpi" or "utmi".
9
10Required properties for phy_type == ulpi:
11 - nvidia,phy-reset-gpio : The GPIO used to reset the PHY.
12
13Optional properties:
14 - nvidia,has-legacy-mode : boolean indicates whether this controller can
15 operate in legacy mode (as APX 2500 / 2600). In legacy mode some
16 registers are accessed through the APB_MISC base address instead of
17 the USB controller. \ No newline at end of file
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bfd7c69c85a5..2c370c869beb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -393,6 +393,7 @@ config ARCH_GEMINI
393config ARCH_SIRF 393config ARCH_SIRF
394 bool "CSR SiRF" 394 bool "CSR SiRF"
395 select ARCH_REQUIRE_GPIOLIB 395 select ARCH_REQUIRE_GPIOLIB
396 select AUTO_ZRELADDR
396 select COMMON_CLK 397 select COMMON_CLK
397 select GENERIC_CLOCKEVENTS 398 select GENERIC_CLOCKEVENTS
398 select GENERIC_IRQ_CHIP 399 select GENERIC_IRQ_CHIP
@@ -640,6 +641,7 @@ config ARCH_LPC32XX
640config ARCH_TEGRA 641config ARCH_TEGRA
641 bool "NVIDIA Tegra" 642 bool "NVIDIA Tegra"
642 select ARCH_HAS_CPUFREQ 643 select ARCH_HAS_CPUFREQ
644 select ARCH_REQUIRE_GPIOLIB
643 select CLKDEV_LOOKUP 645 select CLKDEV_LOOKUP
644 select CLKSRC_MMIO 646 select CLKSRC_MMIO
645 select CLKSRC_OF 647 select CLKSRC_OF
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 5f0cdf28c227..acddddac7ee4 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -205,12 +205,19 @@ choice
205 Say Y here if you want kernel low-level debugging support 205 Say Y here if you want kernel low-level debugging support
206 on i.MX28. 206 on i.MX28.
207 207
208 config DEBUG_IMX31_IMX35_UART 208 config DEBUG_IMX31_UART
209 bool "i.MX31 and i.MX35 Debug UART" 209 bool "i.MX31 Debug UART"
210 depends on SOC_IMX31 || SOC_IMX35 210 depends on SOC_IMX31
211 help 211 help
212 Say Y here if you want kernel low-level debugging support 212 Say Y here if you want kernel low-level debugging support
213 on i.MX31 or i.MX35. 213 on i.MX31.
214
215 config DEBUG_IMX35_UART
216 bool "i.MX35 Debug UART"
217 depends on SOC_IMX35
218 help
219 Say Y here if you want kernel low-level debugging support
220 on i.MX35.
214 221
215 config DEBUG_IMX51_UART 222 config DEBUG_IMX51_UART
216 bool "i.MX51 Debug UART" 223 bool "i.MX51 Debug UART"
@@ -393,6 +400,20 @@ choice
393 Say Y here if you want kernel low-level debugging support 400 Say Y here if you want kernel low-level debugging support
394 on Tegra based platforms. 401 on Tegra based platforms.
395 402
403 config DEBUG_SIRFPRIMA2_UART1
404 bool "Kernel low-level debugging messages via SiRFprimaII UART1"
405 depends on ARCH_PRIMA2
406 help
407 Say Y here if you want the debug print routines to direct
408 their output to the uart1 port on SiRFprimaII devices.
409
410 config DEBUG_SIRFMARCO_UART1
411 bool "Kernel low-level debugging messages via SiRFmarco UART1"
412 depends on ARCH_MARCO
413 help
414 Say Y here if you want the debug print routines to direct
415 their output to the uart1 port on SiRFmarco devices.
416
396 config DEBUG_VEXPRESS_UART0_DETECT 417 config DEBUG_VEXPRESS_UART0_DETECT
397 bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" 418 bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
398 depends on ARCH_VEXPRESS && CPU_CP15_MMU 419 depends on ARCH_VEXPRESS && CPU_CP15_MMU
@@ -464,11 +485,16 @@ choice
464 485
465endchoice 486endchoice
466 487
467config DEBUG_IMX6Q_UART_PORT 488config DEBUG_IMX_UART_PORT
468 int "i.MX6Q Debug UART Port (1-5)" if DEBUG_IMX6Q_UART 489 int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \
469 range 1 5 490 DEBUG_IMX25_UART || \
491 DEBUG_IMX21_IMX27_UART || \
492 DEBUG_IMX31_UART || \
493 DEBUG_IMX35_UART || \
494 DEBUG_IMX51_UART || \
495 DEBUG_IMX50_IMX53_UART || \
496 DEBUG_IMX6Q_UART
470 default 1 497 default 1
471 depends on SOC_IMX6Q
472 help 498 help
473 Choose UART port on which kernel low-level debug messages 499 Choose UART port on which kernel low-level debug messages
474 should be output. 500 should be output.
@@ -557,7 +583,8 @@ config DEBUG_LL_INCLUDE
557 default "debug/imx.S" if DEBUG_IMX1_UART || \ 583 default "debug/imx.S" if DEBUG_IMX1_UART || \
558 DEBUG_IMX25_UART || \ 584 DEBUG_IMX25_UART || \
559 DEBUG_IMX21_IMX27_UART || \ 585 DEBUG_IMX21_IMX27_UART || \
560 DEBUG_IMX31_IMX35_UART || \ 586 DEBUG_IMX31_UART || \
587 DEBUG_IMX35_UART || \
561 DEBUG_IMX51_UART || \ 588 DEBUG_IMX51_UART || \
562 DEBUG_IMX53_UART ||\ 589 DEBUG_IMX53_UART ||\
563 DEBUG_IMX6Q_UART 590 DEBUG_IMX6Q_UART
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 5ebb44fe826a..042f2111485b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -73,6 +73,7 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \
73 kirkwood-ts219-6281.dtb \ 73 kirkwood-ts219-6281.dtb \
74 kirkwood-ts219-6282.dtb \ 74 kirkwood-ts219-6282.dtb \
75 kirkwood-openblocks_a6.dtb 75 kirkwood-openblocks_a6.dtb
76dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
76dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \ 77dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \
77 msm8960-cdp.dtb 78 msm8960-cdp.dtb
78dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ 79dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
@@ -124,6 +125,8 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
124 r8a7740-armadillo800eva.dtb \ 125 r8a7740-armadillo800eva.dtb \
125 sh73a0-kzm9g.dtb \ 126 sh73a0-kzm9g.dtb \
126 sh7372-mackerel.dtb 127 sh7372-mackerel.dtb
128dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \
129 socfpga_vt.dtb
127dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \ 130dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \
128 spear1340-evb.dtb 131 spear1340-evb.dtb
129dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ 132dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
@@ -143,7 +146,9 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
143 tegra20-ventana.dtb \ 146 tegra20-ventana.dtb \
144 tegra20-whistler.dtb \ 147 tegra20-whistler.dtb \
145 tegra30-cardhu-a02.dtb \ 148 tegra30-cardhu-a02.dtb \
146 tegra30-cardhu-a04.dtb 149 tegra30-cardhu-a04.dtb \
150 tegra114-dalmore.dtb \
151 tegra114-pluto.dtb
147dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ 152dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
148 vexpress-v2p-ca9.dtb \ 153 vexpress-v2p-ca9.dtb \
149 vexpress-v2p-ca15-tc1.dtb \ 154 vexpress-v2p-ca15-tc1.dtb \
@@ -151,7 +156,8 @@ dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
151 xenvm-4.2.dtb 156 xenvm-4.2.dtb
152dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \ 157dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
153 wm8505-ref.dtb \ 158 wm8505-ref.dtb \
154 wm8650-mid.dtb 159 wm8650-mid.dtb \
160 wm8850-w70v2.dtb
155dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb 161dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb
156 162
157targets += dtbs 163targets += dtbs
diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi
index eb504a6c0f4a..c8a8c08b48dd 100644
--- a/arch/arm/boot/dts/emev2.dtsi
+++ b/arch/arm/boot/dts/emev2.dtsi
@@ -15,11 +15,18 @@
15 interrupt-parent = <&gic>; 15 interrupt-parent = <&gic>;
16 16
17 cpus { 17 cpus {
18 #address-cells = <1>;
19 #size-cells = <0>;
20
18 cpu@0 { 21 cpu@0 {
22 device_type = "cpu";
19 compatible = "arm,cortex-a9"; 23 compatible = "arm,cortex-a9";
24 reg = <0>;
20 }; 25 };
21 cpu@1 { 26 cpu@1 {
27 device_type = "cpu";
22 compatible = "arm,cortex-a9"; 28 compatible = "arm,cortex-a9";
29 reg = <1>;
23 }; 30 };
24 }; 31 };
25 32
diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi
index eef7099f3e3c..454c2d175402 100644
--- a/arch/arm/boot/dts/imx31.dtsi
+++ b/arch/arm/boot/dts/imx31.dtsi
@@ -45,6 +45,8 @@
45 compatible = "fsl,imx31-uart", "fsl,imx21-uart"; 45 compatible = "fsl,imx31-uart", "fsl,imx21-uart";
46 reg = <0x43f90000 0x4000>; 46 reg = <0x43f90000 0x4000>;
47 interrupts = <45>; 47 interrupts = <45>;
48 clocks = <&clks 10>, <&clks 30>;
49 clock-names = "ipg", "per";
48 status = "disabled"; 50 status = "disabled";
49 }; 51 };
50 52
@@ -52,12 +54,16 @@
52 compatible = "fsl,imx31-uart", "fsl,imx21-uart"; 54 compatible = "fsl,imx31-uart", "fsl,imx21-uart";
53 reg = <0x43f94000 0x4000>; 55 reg = <0x43f94000 0x4000>;
54 interrupts = <32>; 56 interrupts = <32>;
57 clocks = <&clks 10>, <&clks 31>;
58 clock-names = "ipg", "per";
55 status = "disabled"; 59 status = "disabled";
56 }; 60 };
57 61
58 uart4: serial@43fb0000 { 62 uart4: serial@43fb0000 {
59 compatible = "fsl,imx31-uart", "fsl,imx21-uart"; 63 compatible = "fsl,imx31-uart", "fsl,imx21-uart";
60 reg = <0x43fb0000 0x4000>; 64 reg = <0x43fb0000 0x4000>;
65 clocks = <&clks 10>, <&clks 49>;
66 clock-names = "ipg", "per";
61 interrupts = <46>; 67 interrupts = <46>;
62 status = "disabled"; 68 status = "disabled";
63 }; 69 };
@@ -66,6 +72,8 @@
66 compatible = "fsl,imx31-uart", "fsl,imx21-uart"; 72 compatible = "fsl,imx31-uart", "fsl,imx21-uart";
67 reg = <0x43fb4000 0x4000>; 73 reg = <0x43fb4000 0x4000>;
68 interrupts = <47>; 74 interrupts = <47>;
75 clocks = <&clks 10>, <&clks 50>;
76 clock-names = "ipg", "per";
69 status = "disabled"; 77 status = "disabled";
70 }; 78 };
71 }; 79 };
@@ -81,8 +89,17 @@
81 compatible = "fsl,imx31-uart", "fsl,imx21-uart"; 89 compatible = "fsl,imx31-uart", "fsl,imx21-uart";
82 reg = <0x5000c000 0x4000>; 90 reg = <0x5000c000 0x4000>;
83 interrupts = <18>; 91 interrupts = <18>;
92 clocks = <&clks 10>, <&clks 48>;
93 clock-names = "ipg", "per";
84 status = "disabled"; 94 status = "disabled";
85 }; 95 };
96
97 clks: ccm@53f80000{
98 compatible = "fsl,imx31-ccm";
99 reg = <0x53f80000 0x4000>;
100 interrupts = <0 31 0x04 0 53 0x04>;
101 #clock-cells = <1>;
102 };
86 }; 103 };
87 }; 104 };
88}; 105};
diff --git a/arch/arm/boot/dts/marco-evb.dts b/arch/arm/boot/dts/marco-evb.dts
new file mode 100644
index 000000000000..5130aeacfca5
--- /dev/null
+++ b/arch/arm/boot/dts/marco-evb.dts
@@ -0,0 +1,54 @@
1/*
2 * DTS file for CSR SiRFmarco Evaluation Board
3 *
4 * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9/dts-v1/;
10
11/include/ "marco.dtsi"
12
13/ {
14 model = "CSR SiRFmarco Evaluation Board";
15 compatible = "sirf,marco-cb", "sirf,marco";
16
17 memory {
18 reg = <0x40000000 0x60000000>;
19 };
20
21 axi {
22 peri-iobg {
23 uart1: uart@cc060000 {
24 status = "okay";
25 };
26 uart2: uart@cc070000 {
27 status = "okay";
28 };
29 i2c0: i2c@cc0e0000 {
30 status = "okay";
31 fpga-cpld@4d {
32 compatible = "sirf,fpga-cpld";
33 reg = <0x4d>;
34 };
35 };
36 spi1: spi@cc170000 {
37 status = "okay";
38 pinctrl-names = "default";
39 pinctrl-0 = <&spi1_pins_a>;
40 spi@0 {
41 compatible = "spidev";
42 reg = <0>;
43 spi-max-frequency = <1000000>;
44 };
45 };
46 pci-iobg {
47 sd0: sdhci@cd000000 {
48 bus-width = <8>;
49 status = "okay";
50 };
51 };
52 };
53 };
54};
diff --git a/arch/arm/boot/dts/marco.dtsi b/arch/arm/boot/dts/marco.dtsi
new file mode 100644
index 000000000000..1579c3491ccd
--- /dev/null
+++ b/arch/arm/boot/dts/marco.dtsi
@@ -0,0 +1,756 @@
1/*
2 * DTS file for CSR SiRFmarco SoC
3 *
4 * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9/include/ "skeleton.dtsi"
10/ {
11 compatible = "sirf,marco";
12 #address-cells = <1>;
13 #size-cells = <1>;
14 interrupt-parent = <&gic>;
15
16 cpus {
17 #address-cells = <1>;
18 #size-cells = <0>;
19
20 cpu@0 {
21 device_type = "cpu";
22 compatible = "arm,cortex-a9";
23 reg = <0>;
24 };
25 cpu@1 {
26 device_type = "cpu";
27 compatible = "arm,cortex-a9";
28 reg = <1>;
29 };
30 };
31
32 axi {
33 compatible = "simple-bus";
34 #address-cells = <1>;
35 #size-cells = <1>;
36 ranges = <0x40000000 0x40000000 0xa0000000>;
37
38 l2-cache-controller@c0030000 {
39 compatible = "sirf,marco-pl310-cache", "arm,pl310-cache";
40 reg = <0xc0030000 0x1000>;
41 interrupts = <0 59 0>;
42 arm,tag-latency = <1 1 1>;
43 arm,data-latency = <1 1 1>;
44 arm,filter-ranges = <0x40000000 0x80000000>;
45 };
46
47 gic: interrupt-controller@c0011000 {
48 compatible = "arm,cortex-a9-gic";
49 interrupt-controller;
50 #interrupt-cells = <3>;
51 reg = <0xc0011000 0x1000>,
52 <0xc0010100 0x0100>;
53 };
54
55 rstc-iobg {
56 compatible = "simple-bus";
57 #address-cells = <1>;
58 #size-cells = <1>;
59 ranges = <0xc2000000 0xc2000000 0x1000000>;
60
61 reset-controller@c2000000 {
62 compatible = "sirf,marco-rstc";
63 reg = <0xc2000000 0x10000>;
64 };
65 };
66
67 sys-iobg {
68 compatible = "simple-bus";
69 #address-cells = <1>;
70 #size-cells = <1>;
71 ranges = <0xc3000000 0xc3000000 0x1000000>;
72
73 clock-controller@c3000000 {
74 compatible = "sirf,marco-clkc";
75 reg = <0xc3000000 0x1000>;
76 interrupts = <0 3 0>;
77 };
78
79 rsc-controller@c3010000 {
80 compatible = "sirf,marco-rsc";
81 reg = <0xc3010000 0x1000>;
82 };
83 };
84
85 mem-iobg {
86 compatible = "simple-bus";
87 #address-cells = <1>;
88 #size-cells = <1>;
89 ranges = <0xc4000000 0xc4000000 0x1000000>;
90
91 memory-controller@c4000000 {
92 compatible = "sirf,marco-memc";
93 reg = <0xc4000000 0x10000>;
94 interrupts = <0 27 0>;
95 };
96 };
97
98 disp-iobg0 {
99 compatible = "simple-bus";
100 #address-cells = <1>;
101 #size-cells = <1>;
102 ranges = <0xc5000000 0xc5000000 0x1000000>;
103
104 display0@c5000000 {
105 compatible = "sirf,marco-lcd";
106 reg = <0xc5000000 0x10000>;
107 interrupts = <0 30 0>;
108 };
109
110 vpp0@c5010000 {
111 compatible = "sirf,marco-vpp";
112 reg = <0xc5010000 0x10000>;
113 interrupts = <0 31 0>;
114 };
115 };
116
117 disp-iobg1 {
118 compatible = "simple-bus";
119 #address-cells = <1>;
120 #size-cells = <1>;
121 ranges = <0xc6000000 0xc6000000 0x1000000>;
122
123 display1@c6000000 {
124 compatible = "sirf,marco-lcd";
125 reg = <0xc6000000 0x10000>;
126 interrupts = <0 62 0>;
127 };
128
129 vpp1@c6010000 {
130 compatible = "sirf,marco-vpp";
131 reg = <0xc6010000 0x10000>;
132 interrupts = <0 63 0>;
133 };
134 };
135
136 graphics-iobg {
137 compatible = "simple-bus";
138 #address-cells = <1>;
139 #size-cells = <1>;
140 ranges = <0xc8000000 0xc8000000 0x1000000>;
141
142 graphics@c8000000 {
143 compatible = "powervr,sgx540";
144 reg = <0xc8000000 0x1000000>;
145 interrupts = <0 6 0>;
146 };
147 };
148
149 multimedia-iobg {
150 compatible = "simple-bus";
151 #address-cells = <1>;
152 #size-cells = <1>;
153 ranges = <0xc9000000 0xc9000000 0x1000000>;
154
155 multimedia@a0000000 {
156 compatible = "sirf,marco-video-codec";
157 reg = <0xc9000000 0x1000000>;
158 interrupts = <0 5 0>;
159 };
160 };
161
162 dsp-iobg {
163 compatible = "simple-bus";
164 #address-cells = <1>;
165 #size-cells = <1>;
166 ranges = <0xca000000 0xca000000 0x2000000>;
167
168 dspif@ca000000 {
169 compatible = "sirf,marco-dspif";
170 reg = <0xca000000 0x10000>;
171 interrupts = <0 9 0>;
172 };
173
174 gps@ca010000 {
175 compatible = "sirf,marco-gps";
176 reg = <0xca010000 0x10000>;
177 interrupts = <0 7 0>;
178 };
179
180 dsp@cb000000 {
181 compatible = "sirf,marco-dsp";
182 reg = <0xcb000000 0x1000000>;
183 interrupts = <0 8 0>;
184 };
185 };
186
187 peri-iobg {
188 compatible = "simple-bus";
189 #address-cells = <1>;
190 #size-cells = <1>;
191 ranges = <0xcc000000 0xcc000000 0x2000000>;
192
193 timer@cc020000 {
194 compatible = "sirf,marco-tick";
195 reg = <0xcc020000 0x1000>;
196 interrupts = <0 0 0>,
197 <0 1 0>,
198 <0 2 0>,
199 <0 49 0>,
200 <0 50 0>,
201 <0 51 0>;
202 };
203
204 nand@cc030000 {
205 compatible = "sirf,marco-nand";
206 reg = <0xcc030000 0x10000>;
207 interrupts = <0 41 0>;
208 };
209
210 audio@cc040000 {
211 compatible = "sirf,marco-audio";
212 reg = <0xcc040000 0x10000>;
213 interrupts = <0 35 0>;
214 };
215
216 uart0: uart@cc050000 {
217 cell-index = <0>;
218 compatible = "sirf,marco-uart";
219 reg = <0xcc050000 0x1000>;
220 interrupts = <0 17 0>;
221 fifosize = <128>;
222 status = "disabled";
223 };
224
225 uart1: uart@cc060000 {
226 cell-index = <1>;
227 compatible = "sirf,marco-uart";
228 reg = <0xcc060000 0x1000>;
229 interrupts = <0 18 0>;
230 fifosize = <32>;
231 status = "disabled";
232 };
233
234 uart2: uart@cc070000 {
235 cell-index = <2>;
236 compatible = "sirf,marco-uart";
237 reg = <0xcc070000 0x1000>;
238 interrupts = <0 19 0>;
239 fifosize = <128>;
240 status = "disabled";
241 };
242
243 uart3: uart@cc190000 {
244 cell-index = <3>;
245 compatible = "sirf,marco-uart";
246 reg = <0xcc190000 0x1000>;
247 interrupts = <0 66 0>;
248 fifosize = <128>;
249 status = "disabled";
250 };
251
252 uart4: uart@cc1a0000 {
253 cell-index = <4>;
254 compatible = "sirf,marco-uart";
255 reg = <0xcc1a0000 0x1000>;
256 interrupts = <0 69 0>;
257 fifosize = <128>;
258 status = "disabled";
259 };
260
261 usp0: usp@cc080000 {
262 cell-index = <0>;
263 compatible = "sirf,marco-usp";
264 reg = <0xcc080000 0x10000>;
265 interrupts = <0 20 0>;
266 status = "disabled";
267 };
268
269 usp1: usp@cc090000 {
270 cell-index = <1>;
271 compatible = "sirf,marco-usp";
272 reg = <0xcc090000 0x10000>;
273 interrupts = <0 21 0>;
274 status = "disabled";
275 };
276
277 usp2: usp@cc0a0000 {
278 cell-index = <2>;
279 compatible = "sirf,marco-usp";
280 reg = <0xcc0a0000 0x10000>;
281 interrupts = <0 22 0>;
282 status = "disabled";
283 };
284
285 dmac0: dma-controller@cc0b0000 {
286 cell-index = <0>;
287 compatible = "sirf,marco-dmac";
288 reg = <0xcc0b0000 0x10000>;
289 interrupts = <0 12 0>;
290 };
291
292 dmac1: dma-controller@cc160000 {
293 cell-index = <1>;
294 compatible = "sirf,marco-dmac";
295 reg = <0xcc160000 0x10000>;
296 interrupts = <0 13 0>;
297 };
298
299 vip@cc0c0000 {
300 compatible = "sirf,marco-vip";
301 reg = <0xcc0c0000 0x10000>;
302 };
303
304 spi0: spi@cc0d0000 {
305 cell-index = <0>;
306 compatible = "sirf,marco-spi";
307 reg = <0xcc0d0000 0x10000>;
308 interrupts = <0 15 0>;
309 sirf,spi-num-chipselects = <1>;
310 cs-gpios = <&gpio 0 0>;
311 sirf,spi-dma-rx-channel = <25>;
312 sirf,spi-dma-tx-channel = <20>;
313 #address-cells = <1>;
314 #size-cells = <0>;
315 status = "disabled";
316 };
317
318 spi1: spi@cc170000 {
319 cell-index = <1>;
320 compatible = "sirf,marco-spi";
321 reg = <0xcc170000 0x10000>;
322 interrupts = <0 16 0>;
323 sirf,spi-num-chipselects = <1>;
324 cs-gpios = <&gpio 0 0>;
325 sirf,spi-dma-rx-channel = <12>;
326 sirf,spi-dma-tx-channel = <13>;
327 #address-cells = <1>;
328 #size-cells = <0>;
329 status = "disabled";
330 };
331
332 i2c0: i2c@cc0e0000 {
333 cell-index = <0>;
334 compatible = "sirf,marco-i2c";
335 reg = <0xcc0e0000 0x10000>;
336 interrupts = <0 24 0>;
337 #address-cells = <1>;
338 #size-cells = <0>;
339 status = "disabled";
340 };
341
342 i2c1: i2c@cc0f0000 {
343 cell-index = <1>;
344 compatible = "sirf,marco-i2c";
345 reg = <0xcc0f0000 0x10000>;
346 interrupts = <0 25 0>;
347 #address-cells = <1>;
348 #size-cells = <0>;
349 status = "disabled";
350 };
351
352 tsc@cc110000 {
353 compatible = "sirf,marco-tsc";
354 reg = <0xcc110000 0x10000>;
355 interrupts = <0 33 0>;
356 };
357
358 gpio: pinctrl@cc120000 {
359 #gpio-cells = <2>;
360 #interrupt-cells = <2>;
361 compatible = "sirf,marco-pinctrl";
362 reg = <0xcc120000 0x10000>;
363 interrupts = <0 43 0>,
364 <0 44 0>,
365 <0 45 0>,
366 <0 46 0>,
367 <0 47 0>;
368 gpio-controller;
369 interrupt-controller;
370
371 lcd_16pins_a: lcd0_0 {
372 lcd {
373 sirf,pins = "lcd_16bitsgrp";
374 sirf,function = "lcd_16bits";
375 };
376 };
377 lcd_18pins_a: lcd0_1 {
378 lcd {
379 sirf,pins = "lcd_18bitsgrp";
380 sirf,function = "lcd_18bits";
381 };
382 };
383 lcd_24pins_a: lcd0_2 {
384 lcd {
385 sirf,pins = "lcd_24bitsgrp";
386 sirf,function = "lcd_24bits";
387 };
388 };
389 lcdrom_pins_a: lcdrom0_0 {
390 lcd {
391 sirf,pins = "lcdromgrp";
392 sirf,function = "lcdrom";
393 };
394 };
395 uart0_pins_a: uart0_0 {
396 uart {
397 sirf,pins = "uart0grp";
398 sirf,function = "uart0";
399 };
400 };
401 uart1_pins_a: uart1_0 {
402 uart {
403 sirf,pins = "uart1grp";
404 sirf,function = "uart1";
405 };
406 };
407 uart2_pins_a: uart2_0 {
408 uart {
409 sirf,pins = "uart2grp";
410 sirf,function = "uart2";
411 };
412 };
413 uart2_noflow_pins_a: uart2_1 {
414 uart {
415 sirf,pins = "uart2_nostreamctrlgrp";
416 sirf,function = "uart2_nostreamctrl";
417 };
418 };
419 spi0_pins_a: spi0_0 {
420 spi {
421 sirf,pins = "spi0grp";
422 sirf,function = "spi0";
423 };
424 };
425 spi1_pins_a: spi1_0 {
426 spi {
427 sirf,pins = "spi1grp";
428 sirf,function = "spi1";
429 };
430 };
431 i2c0_pins_a: i2c0_0 {
432 i2c {
433 sirf,pins = "i2c0grp";
434 sirf,function = "i2c0";
435 };
436 };
437 i2c1_pins_a: i2c1_0 {
438 i2c {
439 sirf,pins = "i2c1grp";
440 sirf,function = "i2c1";
441 };
442 };
443 pwm0_pins_a: pwm0_0 {
444 pwm {
445 sirf,pins = "pwm0grp";
446 sirf,function = "pwm0";
447 };
448 };
449 pwm1_pins_a: pwm1_0 {
450 pwm {
451 sirf,pins = "pwm1grp";
452 sirf,function = "pwm1";
453 };
454 };
455 pwm2_pins_a: pwm2_0 {
456 pwm {
457 sirf,pins = "pwm2grp";
458 sirf,function = "pwm2";
459 };
460 };
461 pwm3_pins_a: pwm3_0 {
462 pwm {
463 sirf,pins = "pwm3grp";
464 sirf,function = "pwm3";
465 };
466 };
467 gps_pins_a: gps_0 {
468 gps {
469 sirf,pins = "gpsgrp";
470 sirf,function = "gps";
471 };
472 };
473 vip_pins_a: vip_0 {
474 vip {
475 sirf,pins = "vipgrp";
476 sirf,function = "vip";
477 };
478 };
479 sdmmc0_pins_a: sdmmc0_0 {
480 sdmmc0 {
481 sirf,pins = "sdmmc0grp";
482 sirf,function = "sdmmc0";
483 };
484 };
485 sdmmc1_pins_a: sdmmc1_0 {
486 sdmmc1 {
487 sirf,pins = "sdmmc1grp";
488 sirf,function = "sdmmc1";
489 };
490 };
491 sdmmc2_pins_a: sdmmc2_0 {
492 sdmmc2 {
493 sirf,pins = "sdmmc2grp";
494 sirf,function = "sdmmc2";
495 };
496 };
497 sdmmc3_pins_a: sdmmc3_0 {
498 sdmmc3 {
499 sirf,pins = "sdmmc3grp";
500 sirf,function = "sdmmc3";
501 };
502 };
503 sdmmc4_pins_a: sdmmc4_0 {
504 sdmmc4 {
505 sirf,pins = "sdmmc4grp";
506 sirf,function = "sdmmc4";
507 };
508 };
509 sdmmc5_pins_a: sdmmc5_0 {
510 sdmmc5 {
511 sirf,pins = "sdmmc5grp";
512 sirf,function = "sdmmc5";
513 };
514 };
515 i2s_pins_a: i2s_0 {
516 i2s {
517 sirf,pins = "i2sgrp";
518 sirf,function = "i2s";
519 };
520 };
521 ac97_pins_a: ac97_0 {
522 ac97 {
523 sirf,pins = "ac97grp";
524 sirf,function = "ac97";
525 };
526 };
527 nand_pins_a: nand_0 {
528 nand {
529 sirf,pins = "nandgrp";
530 sirf,function = "nand";
531 };
532 };
533 usp0_pins_a: usp0_0 {
534 usp0 {
535 sirf,pins = "usp0grp";
536 sirf,function = "usp0";
537 };
538 };
539 usp1_pins_a: usp1_0 {
540 usp1 {
541 sirf,pins = "usp1grp";
542 sirf,function = "usp1";
543 };
544 };
545 usp2_pins_a: usp2_0 {
546 usp2 {
547 sirf,pins = "usp2grp";
548 sirf,function = "usp2";
549 };
550 };
551 usb0_utmi_drvbus_pins_a: usb0_utmi_drvbus_0 {
552 usb0_utmi_drvbus {
553 sirf,pins = "usb0_utmi_drvbusgrp";
554 sirf,function = "usb0_utmi_drvbus";
555 };
556 };
557 usb1_utmi_drvbus_pins_a: usb1_utmi_drvbus_0 {
558 usb1_utmi_drvbus {
559 sirf,pins = "usb1_utmi_drvbusgrp";
560 sirf,function = "usb1_utmi_drvbus";
561 };
562 };
563 warm_rst_pins_a: warm_rst_0 {
564 warm_rst {
565 sirf,pins = "warm_rstgrp";
566 sirf,function = "warm_rst";
567 };
568 };
569 pulse_count_pins_a: pulse_count_0 {
570 pulse_count {
571 sirf,pins = "pulse_countgrp";
572 sirf,function = "pulse_count";
573 };
574 };
575 cko0_rst_pins_a: cko0_rst_0 {
576 cko0_rst {
577 sirf,pins = "cko0_rstgrp";
578 sirf,function = "cko0_rst";
579 };
580 };
581 cko1_rst_pins_a: cko1_rst_0 {
582 cko1_rst {
583 sirf,pins = "cko1_rstgrp";
584 sirf,function = "cko1_rst";
585 };
586 };
587 };
588
589 pwm@cc130000 {
590 compatible = "sirf,marco-pwm";
591 reg = <0xcc130000 0x10000>;
592 };
593
594 efusesys@cc140000 {
595 compatible = "sirf,marco-efuse";
596 reg = <0xcc140000 0x10000>;
597 };
598
599 pulsec@cc150000 {
600 compatible = "sirf,marco-pulsec";
601 reg = <0xcc150000 0x10000>;
602 interrupts = <0 48 0>;
603 };
604
605 pci-iobg {
606 compatible = "sirf,marco-pciiobg", "simple-bus";
607 #address-cells = <1>;
608 #size-cells = <1>;
609 ranges = <0xcd000000 0xcd000000 0x1000000>;
610
611 sd0: sdhci@cd000000 {
612 cell-index = <0>;
613 compatible = "sirf,marco-sdhc";
614 reg = <0xcd000000 0x100000>;
615 interrupts = <0 38 0>;
616 status = "disabled";
617 };
618
619 sd1: sdhci@cd100000 {
620 cell-index = <1>;
621 compatible = "sirf,marco-sdhc";
622 reg = <0xcd100000 0x100000>;
623 interrupts = <0 38 0>;
624 status = "disabled";
625 };
626
627 sd2: sdhci@cd200000 {
628 cell-index = <2>;
629 compatible = "sirf,marco-sdhc";
630 reg = <0xcd200000 0x100000>;
631 interrupts = <0 23 0>;
632 status = "disabled";
633 };
634
635 sd3: sdhci@cd300000 {
636 cell-index = <3>;
637 compatible = "sirf,marco-sdhc";
638 reg = <0xcd300000 0x100000>;
639 interrupts = <0 23 0>;
640 status = "disabled";
641 };
642
643 sd4: sdhci@cd400000 {
644 cell-index = <4>;
645 compatible = "sirf,marco-sdhc";
646 reg = <0xcd400000 0x100000>;
647 interrupts = <0 39 0>;
648 status = "disabled";
649 };
650
651 sd5: sdhci@cd500000 {
652 cell-index = <5>;
653 compatible = "sirf,marco-sdhc";
654 reg = <0xcd500000 0x100000>;
655 interrupts = <0 39 0>;
656 status = "disabled";
657 };
658
659 pci-copy@cd900000 {
660 compatible = "sirf,marco-pcicp";
661 reg = <0xcd900000 0x100000>;
662 interrupts = <0 40 0>;
663 };
664
665 rom-interface@cda00000 {
666 compatible = "sirf,marco-romif";
667 reg = <0xcda00000 0x100000>;
668 };
669 };
670 };
671
672 rtc-iobg {
673 compatible = "sirf,marco-rtciobg", "sirf-marco-rtciobg-bus";
674 #address-cells = <1>;
675 #size-cells = <1>;
676 reg = <0xc1000000 0x10000>;
677
678 gpsrtc@1000 {
679 compatible = "sirf,marco-gpsrtc";
680 reg = <0x1000 0x1000>;
681 interrupts = <0 55 0>,
682 <0 56 0>,
683 <0 57 0>;
684 };
685
686 sysrtc@2000 {
687 compatible = "sirf,marco-sysrtc";
688 reg = <0x2000 0x1000>;
689 interrupts = <0 52 0>,
690 <0 53 0>,
691 <0 54 0>;
692 };
693
694 pwrc@3000 {
695 compatible = "sirf,marco-pwrc";
696 reg = <0x3000 0x1000>;
697 interrupts = <0 32 0>;
698 };
699 };
700
701 uus-iobg {
702 compatible = "simple-bus";
703 #address-cells = <1>;
704 #size-cells = <1>;
705 ranges = <0xce000000 0xce000000 0x1000000>;
706
707 usb0: usb@ce000000 {
708 compatible = "chipidea,ci13611a-marco";
709 reg = <0xce000000 0x10000>;
710 interrupts = <0 10 0>;
711 };
712
713 usb1: usb@ce010000 {
714 compatible = "chipidea,ci13611a-marco";
715 reg = <0xce010000 0x10000>;
716 interrupts = <0 11 0>;
717 };
718
719 security@ce020000 {
720 compatible = "sirf,marco-security";
721 reg = <0xce020000 0x10000>;
722 interrupts = <0 42 0>;
723 };
724 };
725
726 can-iobg {
727 compatible = "simple-bus";
728 #address-cells = <1>;
729 #size-cells = <1>;
730 ranges = <0xd0000000 0xd0000000 0x1000000>;
731
732 can0: can@d0000000 {
733 compatible = "sirf,marco-can";
734 reg = <0xd0000000 0x10000>;
735 };
736
737 can1: can@d0010000 {
738 compatible = "sirf,marco-can";
739 reg = <0xd0010000 0x10000>;
740 };
741 };
742
743 lvds-iobg {
744 compatible = "simple-bus";
745 #address-cells = <1>;
746 #size-cells = <1>;
747 ranges = <0xd1000000 0xd1000000 0x1000000>;
748
749 lvds@d1000000 {
750 compatible = "sirf,marco-lvds";
751 reg = <0xd1000000 0x10000>;
752 interrupts = <0 64 0>;
753 };
754 };
755 };
756};
diff --git a/arch/arm/boot/dts/sh73a0-reference.dtsi b/arch/arm/boot/dts/sh73a0-reference.dtsi
new file mode 100644
index 000000000000..d4bb0125b2b2
--- /dev/null
+++ b/arch/arm/boot/dts/sh73a0-reference.dtsi
@@ -0,0 +1,24 @@
1/*
2 * Device Tree Source for the SH73A0 SoC
3 *
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11/include/ "sh73a0.dtsi"
12
13/ {
14 compatible = "renesas,sh73a0";
15
16 mmcif: mmcif@0x10010000 {
17 compatible = "renesas,sh-mmcif";
18 reg = <0xe6bd0000 0x100>;
19 interrupt-parent = <&gic>;
20 interrupts = <0 140 0x4
21 0 141 0x4>;
22 reg-io-width = <4>;
23 };
24};
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
new file mode 100644
index 000000000000..8a59465d0231
--- /dev/null
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -0,0 +1,100 @@
1/*
2 * Device Tree Source for the SH73A0 SoC
3 *
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11/include/ "skeleton.dtsi"
12
13/ {
14 compatible = "renesas,sh73a0";
15
16 cpus {
17 #address-cells = <1>;
18 #size-cells = <0>;
19
20 cpu@0 {
21 device_type = "cpu";
22 compatible = "arm,cortex-a9";
23 reg = <0>;
24 };
25 cpu@1 {
26 device_type = "cpu";
27 compatible = "arm,cortex-a9";
28 reg = <1>;
29 };
30 };
31
32 gic: interrupt-controller@f0001000 {
33 compatible = "arm,cortex-a9-gic";
34 #interrupt-cells = <3>;
35 #address-cells = <1>;
36 interrupt-controller;
37 reg = <0xf0001000 0x1000>,
38 <0xf0000100 0x100>;
39 };
40
41 i2c0: i2c@0xe6820000 {
42 #address-cells = <1>;
43 #size-cells = <0>;
44 compatible = "renesas,rmobile-iic";
45 reg = <0xe6820000 0x425>;
46 interrupt-parent = <&gic>;
47 interrupts = <0 167 0x4
48 0 168 0x4
49 0 169 0x4
50 0 170 0x4>;
51 };
52
53 i2c1: i2c@0xe6822000 {
54 #address-cells = <1>;
55 #size-cells = <0>;
56 compatible = "renesas,rmobile-iic";
57 reg = <0xe6822000 0x425>;
58 interrupt-parent = <&gic>;
59 interrupts = <0 51 0x4
60 0 52 0x4
61 0 53 0x4
62 0 54 0x4>;
63 };
64
65 i2c2: i2c@0xe6824000 {
66 #address-cells = <1>;
67 #size-cells = <0>;
68 compatible = "renesas,rmobile-iic";
69 reg = <0xe6824000 0x425>;
70 interrupt-parent = <&gic>;
71 interrupts = <0 171 0x4
72 0 172 0x4
73 0 173 0x4
74 0 174 0x4>;
75 };
76
77 i2c3: i2c@0xe6826000 {
78 #address-cells = <1>;
79 #size-cells = <0>;
80 compatible = "renesas,rmobile-iic";
81 reg = <0xe6826000 0x425>;
82 interrupt-parent = <&gic>;
83 interrupts = <0 183 0x4
84 0 184 0x4
85 0 185 0x4
86 0 186 0x4>;
87 };
88
89 i2c4: i2c@0xe6828000 {
90 #address-cells = <1>;
91 #size-cells = <0>;
92 compatible = "renesas,rmobile-iic";
93 reg = <0xe6828000 0x425>;
94 interrupt-parent = <&gic>;
95 interrupts = <0 187 0x4
96 0 188 0x4
97 0 189 0x4
98 0 190 0x4>;
99 };
100};
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 19aec421bb26..936d2306e7e1 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -25,6 +25,10 @@
25 ethernet0 = &gmac0; 25 ethernet0 = &gmac0;
26 serial0 = &uart0; 26 serial0 = &uart0;
27 serial1 = &uart1; 27 serial1 = &uart1;
28 timer0 = &timer0;
29 timer1 = &timer1;
30 timer2 = &timer2;
31 timer3 = &timer3;
28 }; 32 };
29 33
30 cpus { 34 cpus {
@@ -98,47 +102,41 @@
98 interrupts = <1 13 0xf04>; 102 interrupts = <1 13 0xf04>;
99 }; 103 };
100 104
101 timer0: timer@ffc08000 { 105 timer0: timer0@ffc08000 {
102 compatible = "snps,dw-apb-timer-sp"; 106 compatible = "snps,dw-apb-timer-sp";
103 interrupts = <0 167 4>; 107 interrupts = <0 167 4>;
104 clock-frequency = <200000000>;
105 reg = <0xffc08000 0x1000>; 108 reg = <0xffc08000 0x1000>;
106 }; 109 };
107 110
108 timer1: timer@ffc09000 { 111 timer1: timer1@ffc09000 {
109 compatible = "snps,dw-apb-timer-sp"; 112 compatible = "snps,dw-apb-timer-sp";
110 interrupts = <0 168 4>; 113 interrupts = <0 168 4>;
111 clock-frequency = <200000000>;
112 reg = <0xffc09000 0x1000>; 114 reg = <0xffc09000 0x1000>;
113 }; 115 };
114 116
115 timer2: timer@ffd00000 { 117 timer2: timer2@ffd00000 {
116 compatible = "snps,dw-apb-timer-osc"; 118 compatible = "snps,dw-apb-timer-osc";
117 interrupts = <0 169 4>; 119 interrupts = <0 169 4>;
118 clock-frequency = <200000000>;
119 reg = <0xffd00000 0x1000>; 120 reg = <0xffd00000 0x1000>;
120 }; 121 };
121 122
122 timer3: timer@ffd01000 { 123 timer3: timer3@ffd01000 {
123 compatible = "snps,dw-apb-timer-osc"; 124 compatible = "snps,dw-apb-timer-osc";
124 interrupts = <0 170 4>; 125 interrupts = <0 170 4>;
125 clock-frequency = <200000000>;
126 reg = <0xffd01000 0x1000>; 126 reg = <0xffd01000 0x1000>;
127 }; 127 };
128 128
129 uart0: uart@ffc02000 { 129 uart0: serial0@ffc02000 {
130 compatible = "snps,dw-apb-uart"; 130 compatible = "snps,dw-apb-uart";
131 reg = <0xffc02000 0x1000>; 131 reg = <0xffc02000 0x1000>;
132 clock-frequency = <7372800>;
133 interrupts = <0 162 4>; 132 interrupts = <0 162 4>;
134 reg-shift = <2>; 133 reg-shift = <2>;
135 reg-io-width = <4>; 134 reg-io-width = <4>;
136 }; 135 };
137 136
138 uart1: uart@ffc03000 { 137 uart1: serial1@ffc03000 {
139 compatible = "snps,dw-apb-uart"; 138 compatible = "snps,dw-apb-uart";
140 reg = <0xffc03000 0x1000>; 139 reg = <0xffc03000 0x1000>;
141 clock-frequency = <7372800>;
142 interrupts = <0 163 4>; 140 interrupts = <0 163 4>;
143 reg-shift = <2>; 141 reg-shift = <2>;
144 reg-io-width = <4>; 142 reg-io-width = <4>;
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dts b/arch/arm/boot/dts/socfpga_cyclone5.dts
index ab7e4a94299f..3ae8a83a0875 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5.dts
@@ -20,7 +20,7 @@
20 20
21/ { 21/ {
22 model = "Altera SOCFPGA Cyclone V"; 22 model = "Altera SOCFPGA Cyclone V";
23 compatible = "altr,socfpga-cyclone5"; 23 compatible = "altr,socfpga-cyclone5", "altr,socfpga";
24 24
25 chosen { 25 chosen {
26 bootargs = "console=ttyS0,57600"; 26 bootargs = "console=ttyS0,57600";
@@ -29,6 +29,36 @@
29 memory { 29 memory {
30 name = "memory"; 30 name = "memory";
31 device_type = "memory"; 31 device_type = "memory";
32 reg = <0x0 0x10000000>; /* 256MB */ 32 reg = <0x0 0x40000000>; /* 1GB */
33 };
34
35 soc {
36 timer0@ffc08000 {
37 clock-frequency = <100000000>;
38 };
39
40 timer1@ffc09000 {
41 clock-frequency = <100000000>;
42 };
43
44 timer2@ffd00000 {
45 clock-frequency = <25000000>;
46 };
47
48 timer3@ffd01000 {
49 clock-frequency = <25000000>;
50 };
51
52 serial0@ffc02000 {
53 clock-frequency = <100000000>;
54 };
55
56 serial1@ffc03000 {
57 clock-frequency = <100000000>;
58 };
59
60 sysmgr@ffd08000 {
61 cpu1-start-addr = <0xffd080c4>;
62 };
33 }; 63 };
34}; 64};
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts
new file mode 100644
index 000000000000..1036eba40bbf
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_vt.dts
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2013 Altera Corporation <www.altera.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/dts-v1/;
19/include/ "socfpga.dtsi"
20
21/ {
22 model = "Altera SOCFPGA VT";
23 compatible = "altr,socfpga-vt", "altr,socfpga";
24
25 chosen {
26 bootargs = "console=ttyS0,57600";
27 };
28
29 memory {
30 name = "memory";
31 device_type = "memory";
32 reg = <0x0 0x40000000>; /* 1 GB */
33 };
34
35 soc {
36 timer0@ffc08000 {
37 clock-frequency = <7000000>;
38 };
39
40 timer1@ffc09000 {
41 clock-frequency = <7000000>;
42 };
43
44 timer2@ffd00000 {
45 clock-frequency = <7000000>;
46 };
47
48 timer3@ffd01000 {
49 clock-frequency = <7000000>;
50 };
51
52 serial0@ffc02000 {
53 clock-frequency = <7372800>;
54 };
55
56 serial1@ffc03000 {
57 clock-frequency = <7372800>;
58 };
59
60 sysmgr@ffd08000 {
61 cpu1-start-addr = <0xffd08010>;
62 };
63 };
64};
diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts
new file mode 100644
index 000000000000..a30aca62658a
--- /dev/null
+++ b/arch/arm/boot/dts/tegra114-dalmore.dts
@@ -0,0 +1,21 @@
1/dts-v1/;
2
3/include/ "tegra114.dtsi"
4
5/ {
6 model = "NVIDIA Tegra114 Dalmore evaluation board";
7 compatible = "nvidia,dalmore", "nvidia,tegra114";
8
9 memory {
10 reg = <0x80000000 0x40000000>;
11 };
12
13 serial@70006300 {
14 status = "okay";
15 clock-frequency = <408000000>;
16 };
17
18 pmc {
19 nvidia,invert-interrupt;
20 };
21};
diff --git a/arch/arm/boot/dts/tegra114-pluto.dts b/arch/arm/boot/dts/tegra114-pluto.dts
new file mode 100644
index 000000000000..9bea8f57aa47
--- /dev/null
+++ b/arch/arm/boot/dts/tegra114-pluto.dts
@@ -0,0 +1,21 @@
1/dts-v1/;
2
3/include/ "tegra114.dtsi"
4
5/ {
6 model = "NVIDIA Tegra114 Pluto evaluation board";
7 compatible = "nvidia,pluto", "nvidia,tegra114";
8
9 memory {
10 reg = <0x80000000 0x40000000>;
11 };
12
13 serial@70006300 {
14 status = "okay";
15 clock-frequency = <408000000>;
16 };
17
18 pmc {
19 nvidia,invert-interrupt;
20 };
21};
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
new file mode 100644
index 000000000000..1dfaf2874c57
--- /dev/null
+++ b/arch/arm/boot/dts/tegra114.dtsi
@@ -0,0 +1,153 @@
1/include/ "skeleton.dtsi"
2
3/ {
4 compatible = "nvidia,tegra114";
5 interrupt-parent = <&gic>;
6
7 gic: interrupt-controller {
8 compatible = "arm,cortex-a15-gic";
9 #interrupt-cells = <3>;
10 interrupt-controller;
11 reg = <0x50041000 0x1000>,
12 <0x50042000 0x1000>,
13 <0x50044000 0x2000>,
14 <0x50046000 0x2000>;
15 interrupts = <1 9 0xf04>;
16 };
17
18 timer@60005000 {
19 compatible = "nvidia,tegra114-timer", "nvidia,tegra20-timer";
20 reg = <0x60005000 0x400>;
21 interrupts = <0 0 0x04
22 0 1 0x04
23 0 41 0x04
24 0 42 0x04
25 0 121 0x04
26 0 122 0x04>;
27 };
28
29 tegra_car: clock {
30 compatible = "nvidia,tegra114-car, nvidia,tegra30-car";
31 reg = <0x60006000 0x1000>;
32 #clock-cells = <1>;
33 };
34
35 ahb: ahb {
36 compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb";
37 reg = <0x6000c004 0x14c>;
38 };
39
40 gpio: gpio {
41 compatible = "nvidia,tegra114-gpio", "nvidia,tegra30-gpio";
42 reg = <0x6000d000 0x1000>;
43 interrupts = <0 32 0x04
44 0 33 0x04
45 0 34 0x04
46 0 35 0x04
47 0 55 0x04
48 0 87 0x04
49 0 89 0x04
50 0 125 0x04>;
51 #gpio-cells = <2>;
52 gpio-controller;
53 #interrupt-cells = <2>;
54 interrupt-controller;
55 };
56
57 pinmux: pinmux {
58 compatible = "nvidia,tegra114-pinmux";
59 reg = <0x70000868 0x148 /* Pad control registers */
60 0x70003000 0x40c>; /* Mux registers */
61 };
62
63 serial@70006000 {
64 compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
65 reg = <0x70006000 0x40>;
66 reg-shift = <2>;
67 interrupts = <0 36 0x04>;
68 status = "disabled";
69 };
70
71 serial@70006040 {
72 compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
73 reg = <0x70006040 0x40>;
74 reg-shift = <2>;
75 interrupts = <0 37 0x04>;
76 status = "disabled";
77 };
78
79 serial@70006200 {
80 compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
81 reg = <0x70006200 0x100>;
82 reg-shift = <2>;
83 interrupts = <0 46 0x04>;
84 status = "disabled";
85 };
86
87 serial@70006300 {
88 compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
89 reg = <0x70006300 0x100>;
90 reg-shift = <2>;
91 interrupts = <0 90 0x04>;
92 status = "disabled";
93 };
94
95 rtc {
96 compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc";
97 reg = <0x7000e000 0x100>;
98 interrupts = <0 2 0x04>;
99 };
100
101 pmc {
102 compatible = "nvidia,tegra114-pmc", "nvidia,tegra30-pmc";
103 reg = <0x7000e400 0x400>;
104 };
105
106 iommu {
107 compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu";
108 reg = <0x7000f010 0x02c
109 0x7000f1f0 0x010
110 0x7000f228 0x074>;
111 nvidia,#asids = <4>;
112 dma-window = <0 0x40000000>;
113 nvidia,swgroups = <0x18659fe>;
114 nvidia,ahb = <&ahb>;
115 };
116
117 cpus {
118 #address-cells = <1>;
119 #size-cells = <0>;
120
121 cpu@0 {
122 device_type = "cpu";
123 compatible = "arm,cortex-a15";
124 reg = <0>;
125 };
126
127 cpu@1 {
128 device_type = "cpu";
129 compatible = "arm,cortex-a15";
130 reg = <1>;
131 };
132
133 cpu@2 {
134 device_type = "cpu";
135 compatible = "arm,cortex-a15";
136 reg = <2>;
137 };
138
139 cpu@3 {
140 device_type = "cpu";
141 compatible = "arm,cortex-a15";
142 reg = <3>;
143 };
144 };
145
146 timer {
147 compatible = "arm,armv7-timer";
148 interrupts = <1 13 0xf08>,
149 <1 14 0xf08>,
150 <1 11 0xf08>,
151 <1 10 0xf08>;
152 };
153};
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts
index 43eb72af8948..2b4169702c8d 100644
--- a/arch/arm/boot/dts/tegra20-harmony.dts
+++ b/arch/arm/boot/dts/tegra20-harmony.dts
@@ -432,6 +432,10 @@
432 status = "okay"; 432 status = "okay";
433 }; 433 };
434 434
435 usb-phy@c5004400 {
436 nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
437 };
438
435 sdhci@c8000200 { 439 sdhci@c8000200 {
436 status = "okay"; 440 status = "okay";
437 cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 441 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts
index 6a93d1404c76..11b30db63ff2 100644
--- a/arch/arm/boot/dts/tegra20-paz00.dts
+++ b/arch/arm/boot/dts/tegra20-paz00.dts
@@ -266,6 +266,8 @@
266 clock-frequency = <80000>; 266 clock-frequency = <80000>;
267 request-gpios = <&gpio 170 0>; /* gpio PV2 */ 267 request-gpios = <&gpio 170 0>; /* gpio PV2 */
268 slave-addr = <138>; 268 slave-addr = <138>;
269 clocks = <&tegra_car 67>, <&tegra_car 124>;
270 clock-names = "div-clk", "fast-clk";
269 }; 271 };
270 272
271 i2c@7000d000 { 273 i2c@7000d000 {
@@ -418,6 +420,10 @@
418 status = "okay"; 420 status = "okay";
419 }; 421 };
420 422
423 usb-phy@c5004400 {
424 nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
425 };
426
421 sdhci@c8000000 { 427 sdhci@c8000000 {
422 status = "okay"; 428 status = "okay";
423 cd-gpios = <&gpio 173 0>; /* gpio PV5 */ 429 cd-gpios = <&gpio 173 0>; /* gpio PV5 */
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index 420459825b46..607bf0c6bf9c 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -561,6 +561,10 @@
561 status = "okay"; 561 status = "okay";
562 }; 562 };
563 563
564 usb-phy@c5004400 {
565 nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
566 };
567
564 sdhci@c8000000 { 568 sdhci@c8000000 {
565 status = "okay"; 569 status = "okay";
566 power-gpios = <&gpio 86 0>; /* gpio PK6 */ 570 power-gpios = <&gpio 86 0>; /* gpio PK6 */
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts
index b70b4cb754c8..e47cf6a58b6f 100644
--- a/arch/arm/boot/dts/tegra20-trimslice.dts
+++ b/arch/arm/boot/dts/tegra20-trimslice.dts
@@ -310,6 +310,10 @@
310 status = "okay"; 310 status = "okay";
311 }; 311 };
312 312
313 usb-phy@c5004400 {
314 nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
315 };
316
313 sdhci@c8000000 { 317 sdhci@c8000000 {
314 status = "okay"; 318 status = "okay";
315 bus-width = <4>; 319 bus-width = <4>;
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts
index adc47547eaae..f6c61d10fd27 100644
--- a/arch/arm/boot/dts/tegra20-ventana.dts
+++ b/arch/arm/boot/dts/tegra20-ventana.dts
@@ -497,6 +497,10 @@
497 status = "okay"; 497 status = "okay";
498 }; 498 };
499 499
500 usb-phy@c5004400 {
501 nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
502 };
503
500 sdhci@c8000000 { 504 sdhci@c8000000 {
501 status = "okay"; 505 status = "okay";
502 power-gpios = <&gpio 86 0>; /* gpio PK6 */ 506 power-gpios = <&gpio 86 0>; /* gpio PK6 */
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index b8effa1cbda7..2e7c83c7253b 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -9,6 +9,7 @@
9 reg = <0x50000000 0x00024000>; 9 reg = <0x50000000 0x00024000>;
10 interrupts = <0 65 0x04 /* mpcore syncpt */ 10 interrupts = <0 65 0x04 /* mpcore syncpt */
11 0 67 0x04>; /* mpcore general */ 11 0 67 0x04>; /* mpcore general */
12 clocks = <&tegra_car 28>;
12 13
13 #address-cells = <1>; 14 #address-cells = <1>;
14 #size-cells = <1>; 15 #size-cells = <1>;
@@ -19,41 +20,49 @@
19 compatible = "nvidia,tegra20-mpe"; 20 compatible = "nvidia,tegra20-mpe";
20 reg = <0x54040000 0x00040000>; 21 reg = <0x54040000 0x00040000>;
21 interrupts = <0 68 0x04>; 22 interrupts = <0 68 0x04>;
23 clocks = <&tegra_car 60>;
22 }; 24 };
23 25
24 vi { 26 vi {
25 compatible = "nvidia,tegra20-vi"; 27 compatible = "nvidia,tegra20-vi";
26 reg = <0x54080000 0x00040000>; 28 reg = <0x54080000 0x00040000>;
27 interrupts = <0 69 0x04>; 29 interrupts = <0 69 0x04>;
30 clocks = <&tegra_car 100>;
28 }; 31 };
29 32
30 epp { 33 epp {
31 compatible = "nvidia,tegra20-epp"; 34 compatible = "nvidia,tegra20-epp";
32 reg = <0x540c0000 0x00040000>; 35 reg = <0x540c0000 0x00040000>;
33 interrupts = <0 70 0x04>; 36 interrupts = <0 70 0x04>;
37 clocks = <&tegra_car 19>;
34 }; 38 };
35 39
36 isp { 40 isp {
37 compatible = "nvidia,tegra20-isp"; 41 compatible = "nvidia,tegra20-isp";
38 reg = <0x54100000 0x00040000>; 42 reg = <0x54100000 0x00040000>;
39 interrupts = <0 71 0x04>; 43 interrupts = <0 71 0x04>;
44 clocks = <&tegra_car 23>;
40 }; 45 };
41 46
42 gr2d { 47 gr2d {
43 compatible = "nvidia,tegra20-gr2d"; 48 compatible = "nvidia,tegra20-gr2d";
44 reg = <0x54140000 0x00040000>; 49 reg = <0x54140000 0x00040000>;
45 interrupts = <0 72 0x04>; 50 interrupts = <0 72 0x04>;
51 clocks = <&tegra_car 21>;
46 }; 52 };
47 53
48 gr3d { 54 gr3d {
49 compatible = "nvidia,tegra20-gr3d"; 55 compatible = "nvidia,tegra20-gr3d";
50 reg = <0x54180000 0x00040000>; 56 reg = <0x54180000 0x00040000>;
57 clocks = <&tegra_car 24>;
51 }; 58 };
52 59
53 dc@54200000 { 60 dc@54200000 {
54 compatible = "nvidia,tegra20-dc"; 61 compatible = "nvidia,tegra20-dc";
55 reg = <0x54200000 0x00040000>; 62 reg = <0x54200000 0x00040000>;
56 interrupts = <0 73 0x04>; 63 interrupts = <0 73 0x04>;
64 clocks = <&tegra_car 27>, <&tegra_car 121>;
65 clock-names = "disp1", "parent";
57 66
58 rgb { 67 rgb {
59 status = "disabled"; 68 status = "disabled";
@@ -64,6 +73,8 @@
64 compatible = "nvidia,tegra20-dc"; 73 compatible = "nvidia,tegra20-dc";
65 reg = <0x54240000 0x00040000>; 74 reg = <0x54240000 0x00040000>;
66 interrupts = <0 74 0x04>; 75 interrupts = <0 74 0x04>;
76 clocks = <&tegra_car 26>, <&tegra_car 121>;
77 clock-names = "disp2", "parent";
67 78
68 rgb { 79 rgb {
69 status = "disabled"; 80 status = "disabled";
@@ -74,6 +85,8 @@
74 compatible = "nvidia,tegra20-hdmi"; 85 compatible = "nvidia,tegra20-hdmi";
75 reg = <0x54280000 0x00040000>; 86 reg = <0x54280000 0x00040000>;
76 interrupts = <0 75 0x04>; 87 interrupts = <0 75 0x04>;
88 clocks = <&tegra_car 51>, <&tegra_car 117>;
89 clock-names = "hdmi", "parent";
77 status = "disabled"; 90 status = "disabled";
78 }; 91 };
79 92
@@ -81,12 +94,14 @@
81 compatible = "nvidia,tegra20-tvo"; 94 compatible = "nvidia,tegra20-tvo";
82 reg = <0x542c0000 0x00040000>; 95 reg = <0x542c0000 0x00040000>;
83 interrupts = <0 76 0x04>; 96 interrupts = <0 76 0x04>;
97 clocks = <&tegra_car 102>;
84 status = "disabled"; 98 status = "disabled";
85 }; 99 };
86 100
87 dsi { 101 dsi {
88 compatible = "nvidia,tegra20-dsi"; 102 compatible = "nvidia,tegra20-dsi";
89 reg = <0x54300000 0x00040000>; 103 reg = <0x54300000 0x00040000>;
104 clocks = <&tegra_car 48>;
90 status = "disabled"; 105 status = "disabled";
91 }; 106 };
92 }; 107 };
@@ -123,6 +138,12 @@
123 0 42 0x04>; 138 0 42 0x04>;
124 }; 139 };
125 140
141 tegra_car: clock {
142 compatible = "nvidia,tegra20-car";
143 reg = <0x60006000 0x1000>;
144 #clock-cells = <1>;
145 };
146
126 apbdma: dma { 147 apbdma: dma {
127 compatible = "nvidia,tegra20-apbdma"; 148 compatible = "nvidia,tegra20-apbdma";
128 reg = <0x6000a000 0x1200>; 149 reg = <0x6000a000 0x1200>;
@@ -142,6 +163,7 @@
142 0 117 0x04 163 0 117 0x04
143 0 118 0x04 164 0 118 0x04
144 0 119 0x04>; 165 0 119 0x04>;
166 clocks = <&tegra_car 34>;
145 }; 167 };
146 168
147 ahb { 169 ahb {
@@ -183,6 +205,7 @@
183 reg = <0x70002800 0x200>; 205 reg = <0x70002800 0x200>;
184 interrupts = <0 13 0x04>; 206 interrupts = <0 13 0x04>;
185 nvidia,dma-request-selector = <&apbdma 2>; 207 nvidia,dma-request-selector = <&apbdma 2>;
208 clocks = <&tegra_car 11>;
186 status = "disabled"; 209 status = "disabled";
187 }; 210 };
188 211
@@ -191,6 +214,7 @@
191 reg = <0x70002a00 0x200>; 214 reg = <0x70002a00 0x200>;
192 interrupts = <0 3 0x04>; 215 interrupts = <0 3 0x04>;
193 nvidia,dma-request-selector = <&apbdma 1>; 216 nvidia,dma-request-selector = <&apbdma 1>;
217 clocks = <&tegra_car 18>;
194 status = "disabled"; 218 status = "disabled";
195 }; 219 };
196 220
@@ -199,6 +223,7 @@
199 reg = <0x70006000 0x40>; 223 reg = <0x70006000 0x40>;
200 reg-shift = <2>; 224 reg-shift = <2>;
201 interrupts = <0 36 0x04>; 225 interrupts = <0 36 0x04>;
226 clocks = <&tegra_car 6>;
202 status = "disabled"; 227 status = "disabled";
203 }; 228 };
204 229
@@ -207,6 +232,7 @@
207 reg = <0x70006040 0x40>; 232 reg = <0x70006040 0x40>;
208 reg-shift = <2>; 233 reg-shift = <2>;
209 interrupts = <0 37 0x04>; 234 interrupts = <0 37 0x04>;
235 clocks = <&tegra_car 96>;
210 status = "disabled"; 236 status = "disabled";
211 }; 237 };
212 238
@@ -215,6 +241,7 @@
215 reg = <0x70006200 0x100>; 241 reg = <0x70006200 0x100>;
216 reg-shift = <2>; 242 reg-shift = <2>;
217 interrupts = <0 46 0x04>; 243 interrupts = <0 46 0x04>;
244 clocks = <&tegra_car 55>;
218 status = "disabled"; 245 status = "disabled";
219 }; 246 };
220 247
@@ -223,6 +250,7 @@
223 reg = <0x70006300 0x100>; 250 reg = <0x70006300 0x100>;
224 reg-shift = <2>; 251 reg-shift = <2>;
225 interrupts = <0 90 0x04>; 252 interrupts = <0 90 0x04>;
253 clocks = <&tegra_car 65>;
226 status = "disabled"; 254 status = "disabled";
227 }; 255 };
228 256
@@ -231,6 +259,7 @@
231 reg = <0x70006400 0x100>; 259 reg = <0x70006400 0x100>;
232 reg-shift = <2>; 260 reg-shift = <2>;
233 interrupts = <0 91 0x04>; 261 interrupts = <0 91 0x04>;
262 clocks = <&tegra_car 66>;
234 status = "disabled"; 263 status = "disabled";
235 }; 264 };
236 265
@@ -238,6 +267,7 @@
238 compatible = "nvidia,tegra20-pwm"; 267 compatible = "nvidia,tegra20-pwm";
239 reg = <0x7000a000 0x100>; 268 reg = <0x7000a000 0x100>;
240 #pwm-cells = <2>; 269 #pwm-cells = <2>;
270 clocks = <&tegra_car 17>;
241 }; 271 };
242 272
243 rtc { 273 rtc {
@@ -252,6 +282,8 @@
252 interrupts = <0 38 0x04>; 282 interrupts = <0 38 0x04>;
253 #address-cells = <1>; 283 #address-cells = <1>;
254 #size-cells = <0>; 284 #size-cells = <0>;
285 clocks = <&tegra_car 12>, <&tegra_car 124>;
286 clock-names = "div-clk", "fast-clk";
255 status = "disabled"; 287 status = "disabled";
256 }; 288 };
257 289
@@ -262,6 +294,7 @@
262 nvidia,dma-request-selector = <&apbdma 11>; 294 nvidia,dma-request-selector = <&apbdma 11>;
263 #address-cells = <1>; 295 #address-cells = <1>;
264 #size-cells = <0>; 296 #size-cells = <0>;
297 clocks = <&tegra_car 43>;
265 status = "disabled"; 298 status = "disabled";
266 }; 299 };
267 300
@@ -271,6 +304,8 @@
271 interrupts = <0 84 0x04>; 304 interrupts = <0 84 0x04>;
272 #address-cells = <1>; 305 #address-cells = <1>;
273 #size-cells = <0>; 306 #size-cells = <0>;
307 clocks = <&tegra_car 54>, <&tegra_car 124>;
308 clock-names = "div-clk", "fast-clk";
274 status = "disabled"; 309 status = "disabled";
275 }; 310 };
276 311
@@ -280,6 +315,8 @@
280 interrupts = <0 92 0x04>; 315 interrupts = <0 92 0x04>;
281 #address-cells = <1>; 316 #address-cells = <1>;
282 #size-cells = <0>; 317 #size-cells = <0>;
318 clocks = <&tegra_car 67>, <&tegra_car 124>;
319 clock-names = "div-clk", "fast-clk";
283 status = "disabled"; 320 status = "disabled";
284 }; 321 };
285 322
@@ -289,6 +326,8 @@
289 interrupts = <0 53 0x04>; 326 interrupts = <0 53 0x04>;
290 #address-cells = <1>; 327 #address-cells = <1>;
291 #size-cells = <0>; 328 #size-cells = <0>;
329 clocks = <&tegra_car 47>, <&tegra_car 124>;
330 clock-names = "div-clk", "fast-clk";
292 status = "disabled"; 331 status = "disabled";
293 }; 332 };
294 333
@@ -299,6 +338,7 @@
299 nvidia,dma-request-selector = <&apbdma 15>; 338 nvidia,dma-request-selector = <&apbdma 15>;
300 #address-cells = <1>; 339 #address-cells = <1>;
301 #size-cells = <0>; 340 #size-cells = <0>;
341 clocks = <&tegra_car 41>;
302 status = "disabled"; 342 status = "disabled";
303 }; 343 };
304 344
@@ -309,6 +349,7 @@
309 nvidia,dma-request-selector = <&apbdma 16>; 349 nvidia,dma-request-selector = <&apbdma 16>;
310 #address-cells = <1>; 350 #address-cells = <1>;
311 #size-cells = <0>; 351 #size-cells = <0>;
352 clocks = <&tegra_car 44>;
312 status = "disabled"; 353 status = "disabled";
313 }; 354 };
314 355
@@ -319,6 +360,7 @@
319 nvidia,dma-request-selector = <&apbdma 17>; 360 nvidia,dma-request-selector = <&apbdma 17>;
320 #address-cells = <1>; 361 #address-cells = <1>;
321 #size-cells = <0>; 362 #size-cells = <0>;
363 clocks = <&tegra_car 46>;
322 status = "disabled"; 364 status = "disabled";
323 }; 365 };
324 366
@@ -329,6 +371,7 @@
329 nvidia,dma-request-selector = <&apbdma 18>; 371 nvidia,dma-request-selector = <&apbdma 18>;
330 #address-cells = <1>; 372 #address-cells = <1>;
331 #size-cells = <0>; 373 #size-cells = <0>;
374 clocks = <&tegra_car 68>;
332 status = "disabled"; 375 status = "disabled";
333 }; 376 };
334 377
@@ -357,12 +400,40 @@
357 #size-cells = <0>; 400 #size-cells = <0>;
358 }; 401 };
359 402
403 phy1: usb-phy@c5000400 {
404 compatible = "nvidia,tegra20-usb-phy";
405 reg = <0xc5000400 0x3c00>;
406 phy_type = "utmi";
407 nvidia,has-legacy-mode;
408 clocks = <&tegra_car 22>, <&tegra_car 127>;
409 clock-names = "phy", "pll_u";
410 };
411
412 phy2: usb-phy@c5004400 {
413 compatible = "nvidia,tegra20-usb-phy";
414 reg = <0xc5004400 0x3c00>;
415 phy_type = "ulpi";
416 clocks = <&tegra_car 94>, <&tegra_car 127>;
417 clock-names = "phy", "pll_u";
418 };
419
420 phy3: usb-phy@c5008400 {
421 compatible = "nvidia,tegra20-usb-phy";
422 reg = <0xc5008400 0x3C00>;
423 phy_type = "utmi";
424 clocks = <&tegra_car 22>, <&tegra_car 127>;
425 clock-names = "phy", "pll_u";
426 };
427
360 usb@c5000000 { 428 usb@c5000000 {
361 compatible = "nvidia,tegra20-ehci", "usb-ehci"; 429 compatible = "nvidia,tegra20-ehci", "usb-ehci";
362 reg = <0xc5000000 0x4000>; 430 reg = <0xc5000000 0x4000>;
363 interrupts = <0 20 0x04>; 431 interrupts = <0 20 0x04>;
364 phy_type = "utmi"; 432 phy_type = "utmi";
365 nvidia,has-legacy-mode; 433 nvidia,has-legacy-mode;
434 clocks = <&tegra_car 22>;
435 nvidia,needs-double-reset;
436 nvidia,phy = <&phy1>;
366 status = "disabled"; 437 status = "disabled";
367 }; 438 };
368 439
@@ -371,6 +442,8 @@
371 reg = <0xc5004000 0x4000>; 442 reg = <0xc5004000 0x4000>;
372 interrupts = <0 21 0x04>; 443 interrupts = <0 21 0x04>;
373 phy_type = "ulpi"; 444 phy_type = "ulpi";
445 clocks = <&tegra_car 58>;
446 nvidia,phy = <&phy2>;
374 status = "disabled"; 447 status = "disabled";
375 }; 448 };
376 449
@@ -379,6 +452,8 @@
379 reg = <0xc5008000 0x4000>; 452 reg = <0xc5008000 0x4000>;
380 interrupts = <0 97 0x04>; 453 interrupts = <0 97 0x04>;
381 phy_type = "utmi"; 454 phy_type = "utmi";
455 clocks = <&tegra_car 59>;
456 nvidia,phy = <&phy3>;
382 status = "disabled"; 457 status = "disabled";
383 }; 458 };
384 459
@@ -386,6 +461,7 @@
386 compatible = "nvidia,tegra20-sdhci"; 461 compatible = "nvidia,tegra20-sdhci";
387 reg = <0xc8000000 0x200>; 462 reg = <0xc8000000 0x200>;
388 interrupts = <0 14 0x04>; 463 interrupts = <0 14 0x04>;
464 clocks = <&tegra_car 14>;
389 status = "disabled"; 465 status = "disabled";
390 }; 466 };
391 467
@@ -393,6 +469,7 @@
393 compatible = "nvidia,tegra20-sdhci"; 469 compatible = "nvidia,tegra20-sdhci";
394 reg = <0xc8000200 0x200>; 470 reg = <0xc8000200 0x200>;
395 interrupts = <0 15 0x04>; 471 interrupts = <0 15 0x04>;
472 clocks = <&tegra_car 9>;
396 status = "disabled"; 473 status = "disabled";
397 }; 474 };
398 475
@@ -400,6 +477,7 @@
400 compatible = "nvidia,tegra20-sdhci"; 477 compatible = "nvidia,tegra20-sdhci";
401 reg = <0xc8000400 0x200>; 478 reg = <0xc8000400 0x200>;
402 interrupts = <0 19 0x04>; 479 interrupts = <0 19 0x04>;
480 clocks = <&tegra_car 69>;
403 status = "disabled"; 481 status = "disabled";
404 }; 482 };
405 483
@@ -407,9 +485,27 @@
407 compatible = "nvidia,tegra20-sdhci"; 485 compatible = "nvidia,tegra20-sdhci";
408 reg = <0xc8000600 0x200>; 486 reg = <0xc8000600 0x200>;
409 interrupts = <0 31 0x04>; 487 interrupts = <0 31 0x04>;
488 clocks = <&tegra_car 15>;
410 status = "disabled"; 489 status = "disabled";
411 }; 490 };
412 491
492 cpus {
493 #address-cells = <1>;
494 #size-cells = <0>;
495
496 cpu@0 {
497 device_type = "cpu";
498 compatible = "arm,cortex-a9";
499 reg = <0>;
500 };
501
502 cpu@1 {
503 device_type = "cpu";
504 compatible = "arm,cortex-a9";
505 reg = <1>;
506 };
507 };
508
413 pmu { 509 pmu {
414 compatible = "arm,cortex-a9-pmu"; 510 compatible = "arm,cortex-a9-pmu";
415 interrupts = <0 56 0x04 511 interrupts = <0 56 0x04
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 529fdb82dfdb..2de8b919d78c 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -9,6 +9,7 @@
9 reg = <0x50000000 0x00024000>; 9 reg = <0x50000000 0x00024000>;
10 interrupts = <0 65 0x04 /* mpcore syncpt */ 10 interrupts = <0 65 0x04 /* mpcore syncpt */
11 0 67 0x04>; /* mpcore general */ 11 0 67 0x04>; /* mpcore general */
12 clocks = <&tegra_car 28>;
12 13
13 #address-cells = <1>; 14 #address-cells = <1>;
14 #size-cells = <1>; 15 #size-cells = <1>;
@@ -19,41 +20,50 @@
19 compatible = "nvidia,tegra30-mpe"; 20 compatible = "nvidia,tegra30-mpe";
20 reg = <0x54040000 0x00040000>; 21 reg = <0x54040000 0x00040000>;
21 interrupts = <0 68 0x04>; 22 interrupts = <0 68 0x04>;
23 clocks = <&tegra_car 60>;
22 }; 24 };
23 25
24 vi { 26 vi {
25 compatible = "nvidia,tegra30-vi"; 27 compatible = "nvidia,tegra30-vi";
26 reg = <0x54080000 0x00040000>; 28 reg = <0x54080000 0x00040000>;
27 interrupts = <0 69 0x04>; 29 interrupts = <0 69 0x04>;
30 clocks = <&tegra_car 164>;
28 }; 31 };
29 32
30 epp { 33 epp {
31 compatible = "nvidia,tegra30-epp"; 34 compatible = "nvidia,tegra30-epp";
32 reg = <0x540c0000 0x00040000>; 35 reg = <0x540c0000 0x00040000>;
33 interrupts = <0 70 0x04>; 36 interrupts = <0 70 0x04>;
37 clocks = <&tegra_car 19>;
34 }; 38 };
35 39
36 isp { 40 isp {
37 compatible = "nvidia,tegra30-isp"; 41 compatible = "nvidia,tegra30-isp";
38 reg = <0x54100000 0x00040000>; 42 reg = <0x54100000 0x00040000>;
39 interrupts = <0 71 0x04>; 43 interrupts = <0 71 0x04>;
44 clocks = <&tegra_car 23>;
40 }; 45 };
41 46
42 gr2d { 47 gr2d {
43 compatible = "nvidia,tegra30-gr2d"; 48 compatible = "nvidia,tegra30-gr2d";
44 reg = <0x54140000 0x00040000>; 49 reg = <0x54140000 0x00040000>;
45 interrupts = <0 72 0x04>; 50 interrupts = <0 72 0x04>;
51 clocks = <&tegra_car 21>;
46 }; 52 };
47 53
48 gr3d { 54 gr3d {
49 compatible = "nvidia,tegra30-gr3d"; 55 compatible = "nvidia,tegra30-gr3d";
50 reg = <0x54180000 0x00040000>; 56 reg = <0x54180000 0x00040000>;
57 clocks = <&tegra_car 24 &tegra_car 98>;
58 clock-names = "3d", "3d2";
51 }; 59 };
52 60
53 dc@54200000 { 61 dc@54200000 {
54 compatible = "nvidia,tegra30-dc"; 62 compatible = "nvidia,tegra30-dc";
55 reg = <0x54200000 0x00040000>; 63 reg = <0x54200000 0x00040000>;
56 interrupts = <0 73 0x04>; 64 interrupts = <0 73 0x04>;
65 clocks = <&tegra_car 27>, <&tegra_car 179>;
66 clock-names = "disp1", "parent";
57 67
58 rgb { 68 rgb {
59 status = "disabled"; 69 status = "disabled";
@@ -64,6 +74,8 @@
64 compatible = "nvidia,tegra30-dc"; 74 compatible = "nvidia,tegra30-dc";
65 reg = <0x54240000 0x00040000>; 75 reg = <0x54240000 0x00040000>;
66 interrupts = <0 74 0x04>; 76 interrupts = <0 74 0x04>;
77 clocks = <&tegra_car 26>, <&tegra_car 179>;
78 clock-names = "disp2", "parent";
67 79
68 rgb { 80 rgb {
69 status = "disabled"; 81 status = "disabled";
@@ -74,6 +86,8 @@
74 compatible = "nvidia,tegra30-hdmi"; 86 compatible = "nvidia,tegra30-hdmi";
75 reg = <0x54280000 0x00040000>; 87 reg = <0x54280000 0x00040000>;
76 interrupts = <0 75 0x04>; 88 interrupts = <0 75 0x04>;
89 clocks = <&tegra_car 51>, <&tegra_car 189>;
90 clock-names = "hdmi", "parent";
77 status = "disabled"; 91 status = "disabled";
78 }; 92 };
79 93
@@ -81,12 +95,14 @@
81 compatible = "nvidia,tegra30-tvo"; 95 compatible = "nvidia,tegra30-tvo";
82 reg = <0x542c0000 0x00040000>; 96 reg = <0x542c0000 0x00040000>;
83 interrupts = <0 76 0x04>; 97 interrupts = <0 76 0x04>;
98 clocks = <&tegra_car 169>;
84 status = "disabled"; 99 status = "disabled";
85 }; 100 };
86 101
87 dsi { 102 dsi {
88 compatible = "nvidia,tegra30-dsi"; 103 compatible = "nvidia,tegra30-dsi";
89 reg = <0x54300000 0x00040000>; 104 reg = <0x54300000 0x00040000>;
105 clocks = <&tegra_car 48>;
90 status = "disabled"; 106 status = "disabled";
91 }; 107 };
92 }; 108 };
@@ -125,6 +141,12 @@
125 0 122 0x04>; 141 0 122 0x04>;
126 }; 142 };
127 143
144 tegra_car: clock {
145 compatible = "nvidia,tegra30-car";
146 reg = <0x60006000 0x1000>;
147 #clock-cells = <1>;
148 };
149
128 apbdma: dma { 150 apbdma: dma {
129 compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; 151 compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
130 reg = <0x6000a000 0x1400>; 152 reg = <0x6000a000 0x1400>;
@@ -160,6 +182,7 @@
160 0 141 0x04 182 0 141 0x04
161 0 142 0x04 183 0 142 0x04
162 0 143 0x04>; 184 0 143 0x04>;
185 clocks = <&tegra_car 34>;
163 }; 186 };
164 187
165 ahb: ahb { 188 ahb: ahb {
@@ -195,6 +218,7 @@
195 reg = <0x70006000 0x40>; 218 reg = <0x70006000 0x40>;
196 reg-shift = <2>; 219 reg-shift = <2>;
197 interrupts = <0 36 0x04>; 220 interrupts = <0 36 0x04>;
221 clocks = <&tegra_car 6>;
198 status = "disabled"; 222 status = "disabled";
199 }; 223 };
200 224
@@ -203,6 +227,7 @@
203 reg = <0x70006040 0x40>; 227 reg = <0x70006040 0x40>;
204 reg-shift = <2>; 228 reg-shift = <2>;
205 interrupts = <0 37 0x04>; 229 interrupts = <0 37 0x04>;
230 clocks = <&tegra_car 160>;
206 status = "disabled"; 231 status = "disabled";
207 }; 232 };
208 233
@@ -211,6 +236,7 @@
211 reg = <0x70006200 0x100>; 236 reg = <0x70006200 0x100>;
212 reg-shift = <2>; 237 reg-shift = <2>;
213 interrupts = <0 46 0x04>; 238 interrupts = <0 46 0x04>;
239 clocks = <&tegra_car 55>;
214 status = "disabled"; 240 status = "disabled";
215 }; 241 };
216 242
@@ -219,6 +245,7 @@
219 reg = <0x70006300 0x100>; 245 reg = <0x70006300 0x100>;
220 reg-shift = <2>; 246 reg-shift = <2>;
221 interrupts = <0 90 0x04>; 247 interrupts = <0 90 0x04>;
248 clocks = <&tegra_car 65>;
222 status = "disabled"; 249 status = "disabled";
223 }; 250 };
224 251
@@ -227,6 +254,7 @@
227 reg = <0x70006400 0x100>; 254 reg = <0x70006400 0x100>;
228 reg-shift = <2>; 255 reg-shift = <2>;
229 interrupts = <0 91 0x04>; 256 interrupts = <0 91 0x04>;
257 clocks = <&tegra_car 66>;
230 status = "disabled"; 258 status = "disabled";
231 }; 259 };
232 260
@@ -234,6 +262,7 @@
234 compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm"; 262 compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
235 reg = <0x7000a000 0x100>; 263 reg = <0x7000a000 0x100>;
236 #pwm-cells = <2>; 264 #pwm-cells = <2>;
265 clocks = <&tegra_car 17>;
237 }; 266 };
238 267
239 rtc { 268 rtc {
@@ -248,6 +277,8 @@
248 interrupts = <0 38 0x04>; 277 interrupts = <0 38 0x04>;
249 #address-cells = <1>; 278 #address-cells = <1>;
250 #size-cells = <0>; 279 #size-cells = <0>;
280 clocks = <&tegra_car 12>, <&tegra_car 182>;
281 clock-names = "div-clk", "fast-clk";
251 status = "disabled"; 282 status = "disabled";
252 }; 283 };
253 284
@@ -257,6 +288,8 @@
257 interrupts = <0 84 0x04>; 288 interrupts = <0 84 0x04>;
258 #address-cells = <1>; 289 #address-cells = <1>;
259 #size-cells = <0>; 290 #size-cells = <0>;
291 clocks = <&tegra_car 54>, <&tegra_car 182>;
292 clock-names = "div-clk", "fast-clk";
260 status = "disabled"; 293 status = "disabled";
261 }; 294 };
262 295
@@ -266,6 +299,8 @@
266 interrupts = <0 92 0x04>; 299 interrupts = <0 92 0x04>;
267 #address-cells = <1>; 300 #address-cells = <1>;
268 #size-cells = <0>; 301 #size-cells = <0>;
302 clocks = <&tegra_car 67>, <&tegra_car 182>;
303 clock-names = "div-clk", "fast-clk";
269 status = "disabled"; 304 status = "disabled";
270 }; 305 };
271 306
@@ -275,6 +310,8 @@
275 interrupts = <0 120 0x04>; 310 interrupts = <0 120 0x04>;
276 #address-cells = <1>; 311 #address-cells = <1>;
277 #size-cells = <0>; 312 #size-cells = <0>;
313 clocks = <&tegra_car 103>, <&tegra_car 182>;
314 clock-names = "div-clk", "fast-clk";
278 status = "disabled"; 315 status = "disabled";
279 }; 316 };
280 317
@@ -284,6 +321,8 @@
284 interrupts = <0 53 0x04>; 321 interrupts = <0 53 0x04>;
285 #address-cells = <1>; 322 #address-cells = <1>;
286 #size-cells = <0>; 323 #size-cells = <0>;
324 clocks = <&tegra_car 47>, <&tegra_car 182>;
325 clock-names = "div-clk", "fast-clk";
287 status = "disabled"; 326 status = "disabled";
288 }; 327 };
289 328
@@ -294,6 +333,7 @@
294 nvidia,dma-request-selector = <&apbdma 15>; 333 nvidia,dma-request-selector = <&apbdma 15>;
295 #address-cells = <1>; 334 #address-cells = <1>;
296 #size-cells = <0>; 335 #size-cells = <0>;
336 clocks = <&tegra_car 41>;
297 status = "disabled"; 337 status = "disabled";
298 }; 338 };
299 339
@@ -304,6 +344,7 @@
304 nvidia,dma-request-selector = <&apbdma 16>; 344 nvidia,dma-request-selector = <&apbdma 16>;
305 #address-cells = <1>; 345 #address-cells = <1>;
306 #size-cells = <0>; 346 #size-cells = <0>;
347 clocks = <&tegra_car 44>;
307 status = "disabled"; 348 status = "disabled";
308 }; 349 };
309 350
@@ -314,6 +355,7 @@
314 nvidia,dma-request-selector = <&apbdma 17>; 355 nvidia,dma-request-selector = <&apbdma 17>;
315 #address-cells = <1>; 356 #address-cells = <1>;
316 #size-cells = <0>; 357 #size-cells = <0>;
358 clocks = <&tegra_car 46>;
317 status = "disabled"; 359 status = "disabled";
318 }; 360 };
319 361
@@ -324,6 +366,7 @@
324 nvidia,dma-request-selector = <&apbdma 18>; 366 nvidia,dma-request-selector = <&apbdma 18>;
325 #address-cells = <1>; 367 #address-cells = <1>;
326 #size-cells = <0>; 368 #size-cells = <0>;
369 clocks = <&tegra_car 68>;
327 status = "disabled"; 370 status = "disabled";
328 }; 371 };
329 372
@@ -334,6 +377,7 @@
334 nvidia,dma-request-selector = <&apbdma 27>; 377 nvidia,dma-request-selector = <&apbdma 27>;
335 #address-cells = <1>; 378 #address-cells = <1>;
336 #size-cells = <0>; 379 #size-cells = <0>;
380 clocks = <&tegra_car 104>;
337 status = "disabled"; 381 status = "disabled";
338 }; 382 };
339 383
@@ -344,6 +388,7 @@
344 nvidia,dma-request-selector = <&apbdma 28>; 388 nvidia,dma-request-selector = <&apbdma 28>;
345 #address-cells = <1>; 389 #address-cells = <1>;
346 #size-cells = <0>; 390 #size-cells = <0>;
391 clocks = <&tegra_car 105>;
347 status = "disabled"; 392 status = "disabled";
348 }; 393 };
349 394
@@ -377,7 +422,13 @@
377 0x70080200 0x100>; 422 0x70080200 0x100>;
378 interrupts = <0 103 0x04>; 423 interrupts = <0 103 0x04>;
379 nvidia,dma-request-selector = <&apbdma 1>; 424 nvidia,dma-request-selector = <&apbdma 1>;
380 425 clocks = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>,
426 <&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>,
427 <&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>,
428 <&tegra_car 110>, <&tegra_car 162>;
429 clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
430 "i2s3", "i2s4", "dam0", "dam1", "dam2",
431 "spdif_in";
381 ranges; 432 ranges;
382 #address-cells = <1>; 433 #address-cells = <1>;
383 #size-cells = <1>; 434 #size-cells = <1>;
@@ -386,6 +437,7 @@
386 compatible = "nvidia,tegra30-i2s"; 437 compatible = "nvidia,tegra30-i2s";
387 reg = <0x70080300 0x100>; 438 reg = <0x70080300 0x100>;
388 nvidia,ahub-cif-ids = <4 4>; 439 nvidia,ahub-cif-ids = <4 4>;
440 clocks = <&tegra_car 30>;
389 status = "disabled"; 441 status = "disabled";
390 }; 442 };
391 443
@@ -393,6 +445,7 @@
393 compatible = "nvidia,tegra30-i2s"; 445 compatible = "nvidia,tegra30-i2s";
394 reg = <0x70080400 0x100>; 446 reg = <0x70080400 0x100>;
395 nvidia,ahub-cif-ids = <5 5>; 447 nvidia,ahub-cif-ids = <5 5>;
448 clocks = <&tegra_car 11>;
396 status = "disabled"; 449 status = "disabled";
397 }; 450 };
398 451
@@ -400,6 +453,7 @@
400 compatible = "nvidia,tegra30-i2s"; 453 compatible = "nvidia,tegra30-i2s";
401 reg = <0x70080500 0x100>; 454 reg = <0x70080500 0x100>;
402 nvidia,ahub-cif-ids = <6 6>; 455 nvidia,ahub-cif-ids = <6 6>;
456 clocks = <&tegra_car 18>;
403 status = "disabled"; 457 status = "disabled";
404 }; 458 };
405 459
@@ -407,6 +461,7 @@
407 compatible = "nvidia,tegra30-i2s"; 461 compatible = "nvidia,tegra30-i2s";
408 reg = <0x70080600 0x100>; 462 reg = <0x70080600 0x100>;
409 nvidia,ahub-cif-ids = <7 7>; 463 nvidia,ahub-cif-ids = <7 7>;
464 clocks = <&tegra_car 101>;
410 status = "disabled"; 465 status = "disabled";
411 }; 466 };
412 467
@@ -414,6 +469,7 @@
414 compatible = "nvidia,tegra30-i2s"; 469 compatible = "nvidia,tegra30-i2s";
415 reg = <0x70080700 0x100>; 470 reg = <0x70080700 0x100>;
416 nvidia,ahub-cif-ids = <8 8>; 471 nvidia,ahub-cif-ids = <8 8>;
472 clocks = <&tegra_car 102>;
417 status = "disabled"; 473 status = "disabled";
418 }; 474 };
419 }; 475 };
@@ -422,6 +478,7 @@
422 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; 478 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
423 reg = <0x78000000 0x200>; 479 reg = <0x78000000 0x200>;
424 interrupts = <0 14 0x04>; 480 interrupts = <0 14 0x04>;
481 clocks = <&tegra_car 14>;
425 status = "disabled"; 482 status = "disabled";
426 }; 483 };
427 484
@@ -429,6 +486,7 @@
429 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; 486 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
430 reg = <0x78000200 0x200>; 487 reg = <0x78000200 0x200>;
431 interrupts = <0 15 0x04>; 488 interrupts = <0 15 0x04>;
489 clocks = <&tegra_car 9>;
432 status = "disabled"; 490 status = "disabled";
433 }; 491 };
434 492
@@ -436,6 +494,7 @@
436 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; 494 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
437 reg = <0x78000400 0x200>; 495 reg = <0x78000400 0x200>;
438 interrupts = <0 19 0x04>; 496 interrupts = <0 19 0x04>;
497 clocks = <&tegra_car 69>;
439 status = "disabled"; 498 status = "disabled";
440 }; 499 };
441 500
@@ -443,9 +502,39 @@
443 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; 502 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
444 reg = <0x78000600 0x200>; 503 reg = <0x78000600 0x200>;
445 interrupts = <0 31 0x04>; 504 interrupts = <0 31 0x04>;
505 clocks = <&tegra_car 15>;
446 status = "disabled"; 506 status = "disabled";
447 }; 507 };
448 508
509 cpus {
510 #address-cells = <1>;
511 #size-cells = <0>;
512
513 cpu@0 {
514 device_type = "cpu";
515 compatible = "arm,cortex-a9";
516 reg = <0>;
517 };
518
519 cpu@1 {
520 device_type = "cpu";
521 compatible = "arm,cortex-a9";
522 reg = <1>;
523 };
524
525 cpu@2 {
526 device_type = "cpu";
527 compatible = "arm,cortex-a9";
528 reg = <2>;
529 };
530
531 cpu@3 {
532 device_type = "cpu";
533 compatible = "arm,cortex-a9";
534 reg = <3>;
535 };
536 };
537
449 pmu { 538 pmu {
450 compatible = "arm,cortex-a9-pmu"; 539 compatible = "arm,cortex-a9-pmu";
451 interrupts = <0 144 0x04 540 interrupts = <0 144 0x04
diff --git a/arch/arm/boot/dts/wm8850-w70v2.dts b/arch/arm/boot/dts/wm8850-w70v2.dts
new file mode 100644
index 000000000000..fcc660c89540
--- /dev/null
+++ b/arch/arm/boot/dts/wm8850-w70v2.dts
@@ -0,0 +1,47 @@
1/*
2 * wm8850-w70v2.dts
3 * - Device tree file for Wondermedia WM8850 Tablet
4 * - 'W70-V2' mainboard
5 * - HongLianYing 'HLY070ML268-21A' 7" LCD panel
6 *
7 * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
8 *
9 * Licensed under GPLv2 or later
10 */
11
12/dts-v1/;
13/include/ "wm8850.dtsi"
14
15/ {
16 model = "Wondermedia WM8850-W70v2 Tablet";
17
18 /*
19 * Display node is based on Sascha Hauer's patch on dri-devel.
20 * Added a bpp property to calculate the size of the framebuffer
21 * until the binding is formalized.
22 */
23 display: display@0 {
24 modes {
25 mode0: mode@0 {
26 hactive = <800>;
27 vactive = <480>;
28 hback-porch = <88>;
29 hfront-porch = <40>;
30 hsync-len = <0>;
31 vback-porch = <32>;
32 vfront-porch = <11>;
33 vsync-len = <1>;
34 clock = <0>; /* unused but required */
35 bpp = <16>; /* non-standard but required */
36 };
37 };
38 };
39
40 backlight {
41 compatible = "pwm-backlight";
42 pwms = <&pwm 0 50000 1>; /* duty inverted */
43
44 brightness-levels = <0 40 60 80 100 130 190 255>;
45 default-brightness-level = <5>;
46 };
47};
diff --git a/arch/arm/boot/dts/wm8850.dtsi b/arch/arm/boot/dts/wm8850.dtsi
new file mode 100644
index 000000000000..e8cbfdc87bba
--- /dev/null
+++ b/arch/arm/boot/dts/wm8850.dtsi
@@ -0,0 +1,224 @@
1/*
2 * wm8850.dtsi - Device tree file for Wondermedia WM8850 SoC
3 *
4 * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
5 *
6 * Licensed under GPLv2 or later
7 */
8
9/include/ "skeleton.dtsi"
10
11/ {
12 compatible = "wm,wm8850";
13
14 aliases {
15 serial0 = &uart0;
16 serial1 = &uart1;
17 serial2 = &uart2;
18 serial3 = &uart3;
19 };
20
21 soc {
22 #address-cells = <1>;
23 #size-cells = <1>;
24 compatible = "simple-bus";
25 ranges;
26 interrupt-parent = <&intc0>;
27
28 intc0: interrupt-controller@d8140000 {
29 compatible = "via,vt8500-intc";
30 interrupt-controller;
31 reg = <0xd8140000 0x10000>;
32 #interrupt-cells = <1>;
33 };
34
35 /* Secondary IC cascaded to intc0 */
36 intc1: interrupt-controller@d8150000 {
37 compatible = "via,vt8500-intc";
38 interrupt-controller;
39 #interrupt-cells = <1>;
40 reg = <0xD8150000 0x10000>;
41 interrupts = <56 57 58 59 60 61 62 63>;
42 };
43
44 gpio: gpio-controller@d8110000 {
45 compatible = "wm,wm8650-gpio";
46 gpio-controller;
47 reg = <0xd8110000 0x10000>;
48 #gpio-cells = <3>;
49 };
50
51 pmc@d8130000 {
52 compatible = "via,vt8500-pmc";
53 reg = <0xd8130000 0x1000>;
54
55 clocks {
56 #address-cells = <1>;
57 #size-cells = <0>;
58
59 ref25: ref25M {
60 #clock-cells = <0>;
61 compatible = "fixed-clock";
62 clock-frequency = <25000000>;
63 };
64
65 ref24: ref24M {
66 #clock-cells = <0>;
67 compatible = "fixed-clock";
68 clock-frequency = <24000000>;
69 };
70
71 plla: plla {
72 #clock-cells = <0>;
73 compatible = "wm,wm8750-pll-clock";
74 clocks = <&ref25>;
75 reg = <0x200>;
76 };
77
78 pllb: pllb {
79 #clock-cells = <0>;
80 compatible = "wm,wm8750-pll-clock";
81 clocks = <&ref25>;
82 reg = <0x204>;
83 };
84
85 clkuart0: uart0 {
86 #clock-cells = <0>;
87 compatible = "via,vt8500-device-clock";
88 clocks = <&ref24>;
89 enable-reg = <0x254>;
90 enable-bit = <24>;
91 };
92
93 clkuart1: uart1 {
94 #clock-cells = <0>;
95 compatible = "via,vt8500-device-clock";
96 clocks = <&ref24>;
97 enable-reg = <0x254>;
98 enable-bit = <25>;
99 };
100
101 clkuart2: uart2 {
102 #clock-cells = <0>;
103 compatible = "via,vt8500-device-clock";
104 clocks = <&ref24>;
105 enable-reg = <0x254>;
106 enable-bit = <26>;
107 };
108
109 clkuart3: uart3 {
110 #clock-cells = <0>;
111 compatible = "via,vt8500-device-clock";
112 clocks = <&ref24>;
113 enable-reg = <0x254>;
114 enable-bit = <27>;
115 };
116
117 clkpwm: pwm {
118 #clock-cells = <0>;
119 compatible = "via,vt8500-device-clock";
120 clocks = <&pllb>;
121 divisor-reg = <0x350>;
122 enable-reg = <0x250>;
123 enable-bit = <17>;
124 };
125
126 clksdhc: sdhc {
127 #clock-cells = <0>;
128 compatible = "via,vt8500-device-clock";
129 clocks = <&pllb>;
130 divisor-reg = <0x330>;
131 divisor-mask = <0x3f>;
132 enable-reg = <0x250>;
133 enable-bit = <0>;
134 };
135 };
136 };
137
138 fb@d8051700 {
139 compatible = "wm,wm8505-fb";
140 reg = <0xd8051700 0x200>;
141 display = <&display>;
142 default-mode = <&mode0>;
143 };
144
145 ge_rops@d8050400 {
146 compatible = "wm,prizm-ge-rops";
147 reg = <0xd8050400 0x100>;
148 };
149
150 pwm: pwm@d8220000 {
151 #pwm-cells = <3>;
152 compatible = "via,vt8500-pwm";
153 reg = <0xd8220000 0x100>;
154 clocks = <&clkpwm>;
155 };
156
157 timer@d8130100 {
158 compatible = "via,vt8500-timer";
159 reg = <0xd8130100 0x28>;
160 interrupts = <36>;
161 };
162
163 ehci@d8007900 {
164 compatible = "via,vt8500-ehci";
165 reg = <0xd8007900 0x200>;
166 interrupts = <26>;
167 };
168
169 uhci@d8007b00 {
170 compatible = "platform-uhci";
171 reg = <0xd8007b00 0x200>;
172 interrupts = <26>;
173 };
174
175 uhci@d8008d00 {
176 compatible = "platform-uhci";
177 reg = <0xd8008d00 0x200>;
178 interrupts = <26>;
179 };
180
181 uart0: uart@d8200000 {
182 compatible = "via,vt8500-uart";
183 reg = <0xd8200000 0x1040>;
184 interrupts = <32>;
185 clocks = <&clkuart0>;
186 };
187
188 uart1: uart@d82b0000 {
189 compatible = "via,vt8500-uart";
190 reg = <0xd82b0000 0x1040>;
191 interrupts = <33>;
192 clocks = <&clkuart1>;
193 };
194
195 uart2: uart@d8210000 {
196 compatible = "via,vt8500-uart";
197 reg = <0xd8210000 0x1040>;
198 interrupts = <47>;
199 clocks = <&clkuart2>;
200 };
201
202 uart3: uart@d82c0000 {
203 compatible = "via,vt8500-uart";
204 reg = <0xd82c0000 0x1040>;
205 interrupts = <50>;
206 clocks = <&clkuart3>;
207 };
208
209 rtc@d8100000 {
210 compatible = "via,vt8500-rtc";
211 reg = <0xd8100000 0x10000>;
212 interrupts = <48>;
213 };
214
215 sdhc@d800a000 {
216 compatible = "wm,wm8505-sdhc";
217 reg = <0xd800a000 0x1000>;
218 interrupts = <20 21>;
219 clocks = <&clksdhc>;
220 bus-width = <4>;
221 sdon-inverted;
222 };
223 };
224};
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 6dddbf877b0c..0a3966787563 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -19,6 +19,7 @@ CONFIG_MODULE_SRCVERSION_ALL=y
19CONFIG_ARCH_MXC=y 19CONFIG_ARCH_MXC=y
20CONFIG_ARCH_MULTI_V6=y 20CONFIG_ARCH_MULTI_V6=y
21CONFIG_ARCH_MULTI_V7=y 21CONFIG_ARCH_MULTI_V7=y
22CONFIG_MACH_IMX31_DT=y
22CONFIG_MACH_MX31LILLY=y 23CONFIG_MACH_MX31LILLY=y
23CONFIG_MACH_MX31LITE=y 24CONFIG_MACH_MX31LITE=y
24CONFIG_MACH_PCM037=y 25CONFIG_MACH_PCM037=y
@@ -150,6 +151,7 @@ CONFIG_MFD_MC13XXX_I2C=y
150CONFIG_REGULATOR=y 151CONFIG_REGULATOR=y
151CONFIG_REGULATOR_FIXED_VOLTAGE=y 152CONFIG_REGULATOR_FIXED_VOLTAGE=y
152CONFIG_REGULATOR_DA9052=y 153CONFIG_REGULATOR_DA9052=y
154CONFIG_REGULATOR_ANATOP=y
153CONFIG_REGULATOR_MC13783=y 155CONFIG_REGULATOR_MC13783=y
154CONFIG_REGULATOR_MC13892=y 156CONFIG_REGULATOR_MC13892=y
155CONFIG_MEDIA_SUPPORT=y 157CONFIG_MEDIA_SUPPORT=y
@@ -158,6 +160,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
158CONFIG_MEDIA_CAMERA_SUPPORT=y 160CONFIG_MEDIA_CAMERA_SUPPORT=y
159CONFIG_SOC_CAMERA=y 161CONFIG_SOC_CAMERA=y
160CONFIG_SOC_CAMERA_OV2640=y 162CONFIG_SOC_CAMERA_OV2640=y
163CONFIG_DRM=y
161CONFIG_VIDEO_MX3=y 164CONFIG_VIDEO_MX3=y
162CONFIG_FB=y 165CONFIG_FB=y
163CONFIG_LCD_PLATFORM=y 166CONFIG_LCD_PLATFORM=y
@@ -196,9 +199,14 @@ CONFIG_RTC_CLASS=y
196CONFIG_RTC_INTF_DEV_UIE_EMUL=y 199CONFIG_RTC_INTF_DEV_UIE_EMUL=y
197CONFIG_RTC_DRV_MC13XXX=y 200CONFIG_RTC_DRV_MC13XXX=y
198CONFIG_RTC_DRV_MXC=y 201CONFIG_RTC_DRV_MXC=y
202CONFIG_RTC_DRV_SNVS=y
199CONFIG_DMADEVICES=y 203CONFIG_DMADEVICES=y
200CONFIG_IMX_SDMA=y 204CONFIG_IMX_SDMA=y
201CONFIG_MXS_DMA=y 205CONFIG_MXS_DMA=y
206CONFIG_STAGING=y
207CONFIG_DRM_IMX=y
208CONFIG_DRM_IMX_IPUV3_CORE=y
209CONFIG_DRM_IMX_IPUV3=y
202CONFIG_COMMON_CLK_DEBUG=y 210CONFIG_COMMON_CLK_DEBUG=y
203# CONFIG_IOMMU_SUPPORT is not set 211# CONFIG_IOMMU_SUPPORT is not set
204CONFIG_EXT2_FS=y 212CONFIG_EXT2_FS=y
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
index 93f3794ba5cb..13482ea58b09 100644
--- a/arch/arm/configs/kirkwood_defconfig
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -56,6 +56,7 @@ CONFIG_AEABI=y
56CONFIG_ZBOOT_ROM_TEXT=0x0 56CONFIG_ZBOOT_ROM_TEXT=0x0
57CONFIG_ZBOOT_ROM_BSS=0x0 57CONFIG_ZBOOT_ROM_BSS=0x0
58CONFIG_CPU_IDLE=y 58CONFIG_CPU_IDLE=y
59CONFIG_CPU_IDLE_KIRKWOOD=y
59CONFIG_NET=y 60CONFIG_NET=y
60CONFIG_PACKET=y 61CONFIG_PACKET=y
61CONFIG_UNIX=y 62CONFIG_UNIX=y
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 7bf535104e26..fbbc5bb022d5 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -1,5 +1,7 @@
1CONFIG_EXPERIMENTAL=y 1CONFIG_EXPERIMENTAL=y
2CONFIG_SYSVIPC=y 2CONFIG_SYSVIPC=y
3CONFIG_NO_HZ=y
4CONFIG_HIGH_RES_TIMERS=y
3CONFIG_TASKSTATS=y 5CONFIG_TASKSTATS=y
4CONFIG_TASK_DELAY_ACCT=y 6CONFIG_TASK_DELAY_ACCT=y
5CONFIG_TASK_XACCT=y 7CONFIG_TASK_XACCT=y
@@ -8,7 +10,6 @@ CONFIG_IKCONFIG=y
8CONFIG_IKCONFIG_PROC=y 10CONFIG_IKCONFIG_PROC=y
9# CONFIG_UTS_NS is not set 11# CONFIG_UTS_NS is not set
10# CONFIG_IPC_NS is not set 12# CONFIG_IPC_NS is not set
11# CONFIG_USER_NS is not set
12# CONFIG_PID_NS is not set 13# CONFIG_PID_NS is not set
13# CONFIG_NET_NS is not set 14# CONFIG_NET_NS is not set
14CONFIG_PERF_EVENTS=y 15CONFIG_PERF_EVENTS=y
@@ -24,8 +25,6 @@ CONFIG_BLK_DEV_INTEGRITY=y
24CONFIG_ARCH_MXS=y 25CONFIG_ARCH_MXS=y
25CONFIG_MACH_MXS_DT=y 26CONFIG_MACH_MXS_DT=y
26# CONFIG_ARM_THUMB is not set 27# CONFIG_ARM_THUMB is not set
27CONFIG_NO_HZ=y
28CONFIG_HIGH_RES_TIMERS=y
29CONFIG_PREEMPT_VOLUNTARY=y 28CONFIG_PREEMPT_VOLUNTARY=y
30CONFIG_AEABI=y 29CONFIG_AEABI=y
31CONFIG_AUTO_ZRELADDR=y 30CONFIG_AUTO_ZRELADDR=y
@@ -46,25 +45,34 @@ CONFIG_SYN_COOKIES=y
46CONFIG_CAN=m 45CONFIG_CAN=m
47CONFIG_CAN_RAW=m 46CONFIG_CAN_RAW=m
48CONFIG_CAN_BCM=m 47CONFIG_CAN_BCM=m
49CONFIG_CAN_DEV=m
50CONFIG_CAN_FLEXCAN=m 48CONFIG_CAN_FLEXCAN=m
51# CONFIG_WIRELESS is not set 49# CONFIG_WIRELESS is not set
52CONFIG_DEVTMPFS=y 50CONFIG_DEVTMPFS=y
51CONFIG_DEVTMPFS_MOUNT=y
53# CONFIG_FIRMWARE_IN_KERNEL is not set 52# CONFIG_FIRMWARE_IN_KERNEL is not set
54# CONFIG_BLK_DEV is not set
55CONFIG_MTD=y 53CONFIG_MTD=y
54CONFIG_MTD_CMDLINE_PARTS=y
56CONFIG_MTD_CHAR=y 55CONFIG_MTD_CHAR=y
56CONFIG_MTD_BLOCK=y
57CONFIG_MTD_DATAFLASH=y 57CONFIG_MTD_DATAFLASH=y
58CONFIG_MTD_M25P80 58CONFIG_MTD_M25P80=y
59# CONFIG_M25PXX_USE_FAST_READ is not set
60CONFIG_MTD_SST25L=y
59CONFIG_MTD_NAND=y 61CONFIG_MTD_NAND=y
60CONFIG_MTD_NAND_GPMI_NAND=y 62CONFIG_MTD_NAND_GPMI_NAND=y
63CONFIG_MTD_UBI=y
64# CONFIG_BLK_DEV is not set
65CONFIG_EEPROM_AT24=y
66CONFIG_SCSI=y
67CONFIG_BLK_DEV_SD=y
61CONFIG_NETDEVICES=y 68CONFIG_NETDEVICES=y
62CONFIG_NET_ETHERNET=y
63CONFIG_ENC28J60=y 69CONFIG_ENC28J60=y
64CONFIG_USB_USBNET=y 70CONFIG_USB_USBNET=y
65CONFIG_USB_NET_SMSC95XX=y 71CONFIG_USB_NET_SMSC95XX=y
66# CONFIG_NETDEV_1000 is not set 72CONFIG_SMSC_PHY=y
67# CONFIG_NETDEV_10000 is not set 73CONFIG_ICPLUS_PHY=y
74CONFIG_REALTEK_PHY=y
75CONFIG_MICREL_PHY=y
68# CONFIG_WLAN is not set 76# CONFIG_WLAN is not set
69# CONFIG_INPUT_MOUSEDEV_PSAUX is not set 77# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
70CONFIG_INPUT_EVDEV=m 78CONFIG_INPUT_EVDEV=m
@@ -91,21 +99,6 @@ CONFIG_SPI_MXS=y
91CONFIG_DEBUG_GPIO=y 99CONFIG_DEBUG_GPIO=y
92CONFIG_GPIO_SYSFS=y 100CONFIG_GPIO_SYSFS=y
93# CONFIG_HWMON is not set 101# CONFIG_HWMON is not set
94# CONFIG_MFD_SUPPORT is not set
95CONFIG_DISPLAY_SUPPORT=m
96# CONFIG_HID_SUPPORT is not set
97CONFIG_SOUND=y
98CONFIG_SND=y
99CONFIG_SND_TIMER=y
100CONFIG_SND_PCM=y
101CONFIG_SND_JACK=y
102CONFIG_SND_DRIVERS=y
103CONFIG_SND_ARM=y
104CONFIG_SND_SOC=y
105CONFIG_SND_MXS_SOC=y
106CONFIG_SND_SOC_MXS_SGTL5000=y
107CONFIG_SND_SOC_I2C_AND_SPI=y
108CONFIG_SND_SOC_SGTL5000=y
109CONFIG_REGULATOR=y 102CONFIG_REGULATOR=y
110CONFIG_REGULATOR_FIXED_VOLTAGE=y 103CONFIG_REGULATOR_FIXED_VOLTAGE=y
111CONFIG_FB=y 104CONFIG_FB=y
@@ -117,13 +110,16 @@ CONFIG_BACKLIGHT_PWM=y
117CONFIG_FRAMEBUFFER_CONSOLE=y 110CONFIG_FRAMEBUFFER_CONSOLE=y
118CONFIG_FONTS=y 111CONFIG_FONTS=y
119CONFIG_LOGO=y 112CONFIG_LOGO=y
113CONFIG_SOUND=y
114CONFIG_SND=y
115CONFIG_SND_SOC=y
116CONFIG_SND_MXS_SOC=y
117CONFIG_SND_SOC_MXS_SGTL5000=y
120CONFIG_USB=y 118CONFIG_USB=y
121CONFIG_USB_CHIPIDEA=y 119CONFIG_USB_CHIPIDEA=y
122CONFIG_USB_CHIPIDEA_HOST=y 120CONFIG_USB_CHIPIDEA_HOST=y
123CONFIG_USB_STORAGE=y 121CONFIG_USB_STORAGE=y
124CONFIG_USB_MXS_PHY=y 122CONFIG_USB_MXS_PHY=y
125CONFIG_SCSI=y
126CONFIG_BLK_DEV_SD=y
127CONFIG_MMC=y 123CONFIG_MMC=y
128CONFIG_MMC_MXS=y 124CONFIG_MMC_MXS=y
129CONFIG_NEW_LEDS=y 125CONFIG_NEW_LEDS=y
@@ -147,16 +143,23 @@ CONFIG_COMMON_CLK_DEBUG=y
147CONFIG_IIO=y 143CONFIG_IIO=y
148CONFIG_PWM=y 144CONFIG_PWM=y
149CONFIG_PWM_MXS=y 145CONFIG_PWM_MXS=y
146CONFIG_EXT2_FS=y
147CONFIG_EXT2_FS_XATTR=y
150CONFIG_EXT3_FS=y 148CONFIG_EXT3_FS=y
149CONFIG_EXT4_FS=y
151# CONFIG_DNOTIFY is not set 150# CONFIG_DNOTIFY is not set
152CONFIG_FSCACHE=m 151CONFIG_FSCACHE=m
153CONFIG_FSCACHE_STATS=y 152CONFIG_FSCACHE_STATS=y
154CONFIG_CACHEFILES=m 153CONFIG_CACHEFILES=m
155CONFIG_TMPFS=y 154CONFIG_TMPFS=y
156CONFIG_TMPFS_POSIX_ACL=y 155CONFIG_TMPFS_POSIX_ACL=y
157# CONFIG_MISC_FILESYSTEMS is not set 156CONFIG_JFFS2_FS=y
157CONFIG_JFFS2_COMPRESSION_OPTIONS=y
158CONFIG_JFFS2_LZO=y
159CONFIG_JFFS2_RUBIN=y
160CONFIG_UBIFS_FS=y
161CONFIG_UBIFS_FS_ADVANCED_COMPR=y
158CONFIG_NFS_FS=y 162CONFIG_NFS_FS=y
159CONFIG_NFS_V3=y
160CONFIG_NFS_V3_ACL=y 163CONFIG_NFS_V3_ACL=y
161CONFIG_NFS_V4=y 164CONFIG_NFS_V4=y
162CONFIG_ROOT_NFS=y 165CONFIG_ROOT_NFS=y
@@ -170,17 +173,12 @@ CONFIG_MAGIC_SYSRQ=y
170CONFIG_UNUSED_SYMBOLS=y 173CONFIG_UNUSED_SYMBOLS=y
171CONFIG_DEBUG_KERNEL=y 174CONFIG_DEBUG_KERNEL=y
172CONFIG_LOCKUP_DETECTOR=y 175CONFIG_LOCKUP_DETECTOR=y
173CONFIG_DETECT_HUNG_TASK=y
174CONFIG_TIMER_STATS=y 176CONFIG_TIMER_STATS=y
175CONFIG_PROVE_LOCKING=y 177CONFIG_PROVE_LOCKING=y
176CONFIG_DEBUG_SPINLOCK_SLEEP=y
177CONFIG_DEBUG_INFO=y 178CONFIG_DEBUG_INFO=y
178CONFIG_SYSCTL_SYSCALL_CHECK=y
179CONFIG_BLK_DEV_IO_TRACE=y 179CONFIG_BLK_DEV_IO_TRACE=y
180CONFIG_STRICT_DEVMEM=y 180CONFIG_STRICT_DEVMEM=y
181CONFIG_DEBUG_USER=y 181CONFIG_DEBUG_USER=y
182CONFIG_CRYPTO=y
183CONFIG_CRYPTO_CRC32C=m
184# CONFIG_CRYPTO_ANSI_CPRNG is not set 182# CONFIG_CRYPTO_ANSI_CPRNG is not set
185# CONFIG_CRYPTO_HW is not set 183# CONFIG_CRYPTO_HW is not set
186CONFIG_CRC_ITU_T=m 184CONFIG_CRC_ITU_T=m
diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig
index 6a936c7c078a..002a1ceadceb 100644
--- a/arch/arm/configs/prima2_defconfig
+++ b/arch/arm/configs/prima2_defconfig
@@ -11,6 +11,9 @@ CONFIG_PARTITION_ADVANCED=y
11CONFIG_BSD_DISKLABEL=y 11CONFIG_BSD_DISKLABEL=y
12CONFIG_SOLARIS_X86_PARTITION=y 12CONFIG_SOLARIS_X86_PARTITION=y
13CONFIG_ARCH_SIRF=y 13CONFIG_ARCH_SIRF=y
14# CONFIG_SWP_EMULATE is not set
15CONFIG_SMP=y
16CONFIG_SCHED_MC=y
14CONFIG_PREEMPT=y 17CONFIG_PREEMPT=y
15CONFIG_AEABI=y 18CONFIG_AEABI=y
16CONFIG_KEXEC=y 19CONFIG_KEXEC=y
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
index 86dff32a0737..18d169373612 100644
--- a/arch/arm/include/asm/smp_scu.h
+++ b/arch/arm/include/asm/smp_scu.h
@@ -6,6 +6,23 @@
6#define SCU_PM_POWEROFF 3 6#define SCU_PM_POWEROFF 3
7 7
8#ifndef __ASSEMBLER__ 8#ifndef __ASSEMBLER__
9
10#include <asm/cputype.h>
11
12static inline bool scu_a9_has_base(void)
13{
14 return read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9;
15}
16
17static inline unsigned long scu_a9_get_base(void)
18{
19 unsigned long pa;
20
21 asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa));
22
23 return pa;
24}
25
9unsigned int scu_get_core_count(void __iomem *); 26unsigned int scu_get_core_count(void __iomem *);
10int scu_power_mode(void __iomem *, unsigned int); 27int scu_power_mode(void __iomem *, unsigned int);
11 28
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
new file mode 100644
index 000000000000..91d38e38a0b4
--- /dev/null
+++ b/arch/arm/include/debug/imx-uart.h
@@ -0,0 +1,88 @@
1/*
2 * Copyright (C) 2012 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __DEBUG_IMX_UART_H
10#define __DEBUG_IMX_UART_H
11
12#define IMX1_UART1_BASE_ADDR 0x00206000
13#define IMX1_UART2_BASE_ADDR 0x00207000
14#define IMX1_UART_BASE_ADDR(n) IMX1_UART##n##_BASE_ADDR
15#define IMX1_UART_BASE(n) IMX1_UART_BASE_ADDR(n)
16
17#define IMX21_UART1_BASE_ADDR 0x1000a000
18#define IMX21_UART2_BASE_ADDR 0x1000b000
19#define IMX21_UART3_BASE_ADDR 0x1000c000
20#define IMX21_UART4_BASE_ADDR 0x1000d000
21#define IMX21_UART_BASE_ADDR(n) IMX21_UART##n##_BASE_ADDR
22#define IMX21_UART_BASE(n) IMX21_UART_BASE_ADDR(n)
23
24#define IMX25_UART1_BASE_ADDR 0x43f90000
25#define IMX25_UART2_BASE_ADDR 0x43f94000
26#define IMX25_UART3_BASE_ADDR 0x5000c000
27#define IMX25_UART4_BASE_ADDR 0x50008000
28#define IMX25_UART5_BASE_ADDR 0x5002c000
29#define IMX25_UART_BASE_ADDR(n) IMX25_UART##n##_BASE_ADDR
30#define IMX25_UART_BASE(n) IMX25_UART_BASE_ADDR(n)
31
32#define IMX31_UART1_BASE_ADDR 0x43f90000
33#define IMX31_UART2_BASE_ADDR 0x43f94000
34#define IMX31_UART3_BASE_ADDR 0x5000c000
35#define IMX31_UART4_BASE_ADDR 0x43fb0000
36#define IMX31_UART5_BASE_ADDR 0x43fb4000
37#define IMX31_UART_BASE_ADDR(n) IMX31_UART##n##_BASE_ADDR
38#define IMX31_UART_BASE(n) IMX31_UART_BASE_ADDR(n)
39
40#define IMX35_UART1_BASE_ADDR 0x43f90000
41#define IMX35_UART2_BASE_ADDR 0x43f94000
42#define IMX35_UART3_BASE_ADDR 0x5000c000
43#define IMX35_UART_BASE_ADDR(n) IMX35_UART##n##_BASE_ADDR
44#define IMX35_UART_BASE(n) IMX35_UART_BASE_ADDR(n)
45
46#define IMX51_UART1_BASE_ADDR 0x73fbc000
47#define IMX51_UART2_BASE_ADDR 0x73fc0000
48#define IMX51_UART3_BASE_ADDR 0x7000c000
49#define IMX51_UART_BASE_ADDR(n) IMX51_UART##n##_BASE_ADDR
50#define IMX51_UART_BASE(n) IMX51_UART_BASE_ADDR(n)
51
52#define IMX53_UART1_BASE_ADDR 0x53fbc000
53#define IMX53_UART2_BASE_ADDR 0x53fc0000
54#define IMX53_UART3_BASE_ADDR 0x5000c000
55#define IMX53_UART4_BASE_ADDR 0x53ff0000
56#define IMX53_UART5_BASE_ADDR 0x63f90000
57#define IMX53_UART_BASE_ADDR(n) IMX53_UART##n##_BASE_ADDR
58#define IMX53_UART_BASE(n) IMX53_UART_BASE_ADDR(n)
59
60#define IMX6Q_UART1_BASE_ADDR 0x02020000
61#define IMX6Q_UART2_BASE_ADDR 0x021e8000
62#define IMX6Q_UART3_BASE_ADDR 0x021ec000
63#define IMX6Q_UART4_BASE_ADDR 0x021f0000
64#define IMX6Q_UART5_BASE_ADDR 0x021f4000
65#define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR
66#define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n)
67
68#define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT)
69
70#ifdef CONFIG_DEBUG_IMX1_UART
71#define UART_PADDR IMX_DEBUG_UART_BASE(IMX1)
72#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
73#define UART_PADDR IMX_DEBUG_UART_BASE(IMX21)
74#elif defined(CONFIG_DEBUG_IMX25_UART)
75#define UART_PADDR IMX_DEBUG_UART_BASE(IMX25)
76#elif defined(CONFIG_DEBUG_IMX31_UART)
77#define UART_PADDR IMX_DEBUG_UART_BASE(IMX31)
78#elif defined(CONFIG_DEBUG_IMX35_UART)
79#define UART_PADDR IMX_DEBUG_UART_BASE(IMX35)
80#elif defined(CONFIG_DEBUG_IMX51_UART)
81#define UART_PADDR IMX_DEBUG_UART_BASE(IMX51)
82#elif defined(CONFIG_DEBUG_IMX53_UART)
83#define UART_PADDR IMX_DEBUG_UART_BASE(IMX53)
84#elif defined(CONFIG_DEBUG_IMX6Q_UART)
85#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6Q)
86#endif
87
88#endif /* __DEBUG_IMX_UART_H */
diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S
index c6f294cf18f0..619d8cc1ac12 100644
--- a/arch/arm/include/debug/imx.S
+++ b/arch/arm/include/debug/imx.S
@@ -10,35 +10,8 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 * 11 *
12 */ 12 */
13#define IMX6Q_UART1_BASE_ADDR 0x02020000
14#define IMX6Q_UART2_BASE_ADDR 0x021e8000
15#define IMX6Q_UART3_BASE_ADDR 0x021ec000
16#define IMX6Q_UART4_BASE_ADDR 0x021f0000
17#define IMX6Q_UART5_BASE_ADDR 0x021f4000
18 13
19/* 14#include "imx-uart.h"
20 * IMX6Q_UART_BASE_ADDR is put in the middle to force the expansion
21 * of IMX6Q_UART##n##_BASE_ADDR.
22 */
23#define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR
24#define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n)
25#define IMX6Q_DEBUG_UART_BASE IMX6Q_UART_BASE(CONFIG_DEBUG_IMX6Q_UART_PORT)
26
27#ifdef CONFIG_DEBUG_IMX1_UART
28#define UART_PADDR 0x00206000
29#elif defined (CONFIG_DEBUG_IMX25_UART)
30#define UART_PADDR 0x43f90000
31#elif defined (CONFIG_DEBUG_IMX21_IMX27_UART)
32#define UART_PADDR 0x1000a000
33#elif defined (CONFIG_DEBUG_IMX31_IMX35_UART)
34#define UART_PADDR 0x43f90000
35#elif defined (CONFIG_DEBUG_IMX51_UART)
36#define UART_PADDR 0x73fbc000
37#elif defined (CONFIG_DEBUG_IMX53_UART)
38#define UART_PADDR 0x53fbc000
39#elif defined (CONFIG_DEBUG_IMX6Q_UART)
40#define UART_PADDR IMX6Q_DEBUG_UART_BASE
41#endif
42 15
43/* 16/*
44 * FIXME: This is a copy of IMX_IO_P2V in hardware.h, and needs to 17 * FIXME: This is a copy of IMX_IO_P2V in hardware.h, and needs to
diff --git a/arch/arm/mach-bcm2835/bcm2835.c b/arch/arm/mach-bcm2835/bcm2835.c
index d615a61e902c..6f5785985dd1 100644
--- a/arch/arm/mach-bcm2835/bcm2835.c
+++ b/arch/arm/mach-bcm2835/bcm2835.c
@@ -26,11 +26,13 @@
26#include <mach/bcm2835_soc.h> 26#include <mach/bcm2835_soc.h>
27 27
28#define PM_RSTC 0x1c 28#define PM_RSTC 0x1c
29#define PM_RSTS 0x20
29#define PM_WDOG 0x24 30#define PM_WDOG 0x24
30 31
31#define PM_PASSWORD 0x5a000000 32#define PM_PASSWORD 0x5a000000
32#define PM_RSTC_WRCFG_MASK 0x00000030 33#define PM_RSTC_WRCFG_MASK 0x00000030
33#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 34#define PM_RSTC_WRCFG_FULL_RESET 0x00000020
35#define PM_RSTS_HADWRH_SET 0x00000040
34 36
35static void __iomem *wdt_regs; 37static void __iomem *wdt_regs;
36 38
@@ -67,6 +69,29 @@ static void bcm2835_restart(char mode, const char *cmd)
67 mdelay(1); 69 mdelay(1);
68} 70}
69 71
72/*
73 * We can't really power off, but if we do the normal reset scheme, and
74 * indicate to bootcode.bin not to reboot, then most of the chip will be
75 * powered off.
76 */
77static void bcm2835_power_off(void)
78{
79 u32 val;
80
81 /*
82 * We set the watchdog hard reset bit here to distinguish this reset
83 * from the normal (full) reset. bootcode.bin will not reboot after a
84 * hard reset.
85 */
86 val = readl_relaxed(wdt_regs + PM_RSTS);
87 val &= ~PM_RSTC_WRCFG_MASK;
88 val |= PM_PASSWORD | PM_RSTS_HADWRH_SET;
89 writel_relaxed(val, wdt_regs + PM_RSTS);
90
91 /* Continue with normal reset mechanism */
92 bcm2835_restart(0, "");
93}
94
70static struct map_desc io_map __initdata = { 95static struct map_desc io_map __initdata = {
71 .virtual = BCM2835_PERIPH_VIRT, 96 .virtual = BCM2835_PERIPH_VIRT,
72 .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS), 97 .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS),
@@ -84,6 +109,9 @@ static void __init bcm2835_init(void)
84 int ret; 109 int ret;
85 110
86 bcm2835_setup_restart(); 111 bcm2835_setup_restart();
112 if (wdt_regs)
113 pm_power_off = bcm2835_power_off;
114
87 bcm2835_init_clocks(); 115 bcm2835_init_clocks();
88 116
89 ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, 117 ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index e3742716cbaa..6da25eebf911 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -652,8 +652,13 @@ static __init void da830_evm_init(void)
652 if (ret) 652 if (ret)
653 pr_warning("da830_evm_init: rtc setup failed: %d\n", ret); 653 pr_warning("da830_evm_init: rtc setup failed: %d\n", ret);
654 654
655 ret = da8xx_register_spi(0, da830evm_spi_info, 655 ret = spi_register_board_info(da830evm_spi_info,
656 ARRAY_SIZE(da830evm_spi_info)); 656 ARRAY_SIZE(da830evm_spi_info));
657 if (ret)
658 pr_warn("%s: spi info registration failed: %d\n", __func__,
659 ret);
660
661 ret = da8xx_register_spi_bus(0, ARRAY_SIZE(da830evm_spi_info));
657 if (ret) 662 if (ret)
658 pr_warning("da830_evm_init: spi 0 registration failed: %d\n", 663 pr_warning("da830_evm_init: spi 0 registration failed: %d\n",
659 ret); 664 ret);
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 3b3356097bb0..3a76a47df39c 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1565,8 +1565,13 @@ static __init void da850_evm_init(void)
1565 1565
1566 da850_vpif_init(); 1566 da850_vpif_init();
1567 1567
1568 ret = da8xx_register_spi(1, da850evm_spi_info, 1568 ret = spi_register_board_info(da850evm_spi_info,
1569 ARRAY_SIZE(da850evm_spi_info)); 1569 ARRAY_SIZE(da850evm_spi_info));
1570 if (ret)
1571 pr_warn("%s: spi info registration failed: %d\n", __func__,
1572 ret);
1573
1574 ret = da8xx_register_spi_bus(1, ARRAY_SIZE(da850evm_spi_info));
1570 if (ret) 1575 if (ret)
1571 pr_warning("da850_evm_init: spi 1 registration failed: %d\n", 1576 pr_warning("da850_evm_init: spi 1 registration failed: %d\n",
1572 ret); 1577 ret);
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index b0df578bf744..9549d53aa63f 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -529,8 +529,13 @@ static void __init mityomapl138_init(void)
529 529
530 mityomapl138_setup_nand(); 530 mityomapl138_setup_nand();
531 531
532 ret = da8xx_register_spi(1, mityomapl138_spi_flash_info, 532 ret = spi_register_board_info(mityomapl138_spi_flash_info,
533 ARRAY_SIZE(mityomapl138_spi_flash_info)); 533 ARRAY_SIZE(mityomapl138_spi_flash_info));
534 if (ret)
535 pr_warn("spi info registration failed: %d\n", ret);
536
537 ret = da8xx_register_spi_bus(1,
538 ARRAY_SIZE(mityomapl138_spi_flash_info));
534 if (ret) 539 if (ret)
535 pr_warning("spi 1 registration failed: %d\n", ret); 540 pr_warning("spi 1 registration failed: %d\n", ret);
536 541
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 34668ead53c7..d458558ee84a 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -52,6 +52,40 @@ static void __clk_disable(struct clk *clk)
52 __clk_disable(clk->parent); 52 __clk_disable(clk->parent);
53} 53}
54 54
55int davinci_clk_reset(struct clk *clk, bool reset)
56{
57 unsigned long flags;
58
59 if (clk == NULL || IS_ERR(clk))
60 return -EINVAL;
61
62 spin_lock_irqsave(&clockfw_lock, flags);
63 if (clk->flags & CLK_PSC)
64 davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
65 spin_unlock_irqrestore(&clockfw_lock, flags);
66
67 return 0;
68}
69EXPORT_SYMBOL(davinci_clk_reset);
70
71int davinci_clk_reset_assert(struct clk *clk)
72{
73 if (clk == NULL || IS_ERR(clk) || !clk->reset)
74 return -EINVAL;
75
76 return clk->reset(clk, true);
77}
78EXPORT_SYMBOL(davinci_clk_reset_assert);
79
80int davinci_clk_reset_deassert(struct clk *clk)
81{
82 if (clk == NULL || IS_ERR(clk) || !clk->reset)
83 return -EINVAL;
84
85 return clk->reset(clk, false);
86}
87EXPORT_SYMBOL(davinci_clk_reset_deassert);
88
55int clk_enable(struct clk *clk) 89int clk_enable(struct clk *clk)
56{ 90{
57 unsigned long flags; 91 unsigned long flags;
@@ -535,7 +569,7 @@ int davinci_set_refclk_rate(unsigned long rate)
535} 569}
536 570
537int __init davinci_clk_init(struct clk_lookup *clocks) 571int __init davinci_clk_init(struct clk_lookup *clocks)
538 { 572{
539 struct clk_lookup *c; 573 struct clk_lookup *c;
540 struct clk *clk; 574 struct clk *clk;
541 size_t num_clocks = 0; 575 size_t num_clocks = 0;
@@ -576,6 +610,9 @@ int __init davinci_clk_init(struct clk_lookup *clocks)
576 if (clk->lpsc) 610 if (clk->lpsc)
577 clk->flags |= CLK_PSC; 611 clk->flags |= CLK_PSC;
578 612
613 if (clk->flags & PSC_LRST)
614 clk->reset = davinci_clk_reset;
615
579 clk_register(clk); 616 clk_register(clk);
580 num_clocks++; 617 num_clocks++;
581 618
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 46f0f1bf1a4c..8694b395fc92 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -103,6 +103,7 @@ struct clk {
103 unsigned long (*recalc) (struct clk *); 103 unsigned long (*recalc) (struct clk *);
104 int (*set_rate) (struct clk *clk, unsigned long rate); 104 int (*set_rate) (struct clk *clk, unsigned long rate);
105 int (*round_rate) (struct clk *clk, unsigned long rate); 105 int (*round_rate) (struct clk *clk, unsigned long rate);
106 int (*reset) (struct clk *clk, bool reset);
106}; 107};
107 108
108/* Clock flags: SoC-specific flags start at BIT(16) */ 109/* Clock flags: SoC-specific flags start at BIT(16) */
@@ -112,6 +113,7 @@ struct clk {
112#define PRE_PLL BIT(4) /* source is before PLL mult/div */ 113#define PRE_PLL BIT(4) /* source is before PLL mult/div */
113#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */ 114#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */
114#define PSC_FORCE BIT(6) /* Force module state transtition */ 115#define PSC_FORCE BIT(6) /* Force module state transtition */
116#define PSC_LRST BIT(8) /* Use local reset on enable/disable */
115 117
116#define CLK(dev, con, ck) \ 118#define CLK(dev, con, ck) \
117 { \ 119 { \
@@ -126,6 +128,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
126int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate); 128int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
127int davinci_set_refclk_rate(unsigned long rate); 129int davinci_set_refclk_rate(unsigned long rate);
128int davinci_simple_set_rate(struct clk *clk, unsigned long rate); 130int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
131int davinci_clk_reset(struct clk *clk, bool reset);
129 132
130extern struct platform_device davinci_wdt_device; 133extern struct platform_device davinci_wdt_device;
131extern void davinci_watchdog_reset(struct platform_device *); 134extern void davinci_watchdog_reset(struct platform_device *);
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 6b9154e9f908..0c4a26ddebba 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -76,6 +76,13 @@ static struct clk pll0_aux_clk = {
76 .flags = CLK_PLL | PRE_PLL, 76 .flags = CLK_PLL | PRE_PLL,
77}; 77};
78 78
79static struct clk pll0_sysclk1 = {
80 .name = "pll0_sysclk1",
81 .parent = &pll0_clk,
82 .flags = CLK_PLL,
83 .div_reg = PLLDIV1,
84};
85
79static struct clk pll0_sysclk2 = { 86static struct clk pll0_sysclk2 = {
80 .name = "pll0_sysclk2", 87 .name = "pll0_sysclk2",
81 .parent = &pll0_clk, 88 .parent = &pll0_clk,
@@ -368,10 +375,19 @@ static struct clk sata_clk = {
368 .flags = PSC_FORCE, 375 .flags = PSC_FORCE,
369}; 376};
370 377
378static struct clk dsp_clk = {
379 .name = "dsp",
380 .parent = &pll0_sysclk1,
381 .domain = DAVINCI_GPSC_DSPDOMAIN,
382 .lpsc = DA8XX_LPSC0_GEM,
383 .flags = PSC_LRST | PSC_FORCE,
384};
385
371static struct clk_lookup da850_clks[] = { 386static struct clk_lookup da850_clks[] = {
372 CLK(NULL, "ref", &ref_clk), 387 CLK(NULL, "ref", &ref_clk),
373 CLK(NULL, "pll0", &pll0_clk), 388 CLK(NULL, "pll0", &pll0_clk),
374 CLK(NULL, "pll0_aux", &pll0_aux_clk), 389 CLK(NULL, "pll0_aux", &pll0_aux_clk),
390 CLK(NULL, "pll0_sysclk1", &pll0_sysclk1),
375 CLK(NULL, "pll0_sysclk2", &pll0_sysclk2), 391 CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
376 CLK(NULL, "pll0_sysclk3", &pll0_sysclk3), 392 CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
377 CLK(NULL, "pll0_sysclk4", &pll0_sysclk4), 393 CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
@@ -413,6 +429,7 @@ static struct clk_lookup da850_clks[] = {
413 CLK("spi_davinci.1", NULL, &spi1_clk), 429 CLK("spi_davinci.1", NULL, &spi1_clk),
414 CLK("vpif", NULL, &vpif_clk), 430 CLK("vpif", NULL, &vpif_clk),
415 CLK("ahci", NULL, &sata_clk), 431 CLK("ahci", NULL, &sata_clk),
432 CLK("davinci-rproc.0", NULL, &dsp_clk),
416 CLK(NULL, NULL, NULL), 433 CLK(NULL, NULL, NULL),
417}; 434};
418 435
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 2d5502d84a22..aa402bc160c8 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -751,7 +751,7 @@ void __iomem * __init da8xx_get_mem_ctlr(void)
751 751
752 da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K); 752 da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K);
753 if (!da8xx_ddr2_ctlr_base) 753 if (!da8xx_ddr2_ctlr_base)
754 pr_warning("%s: Unable to map DDR2 controller", __func__); 754 pr_warn("%s: Unable to map DDR2 controller", __func__);
755 755
756 return da8xx_ddr2_ctlr_base; 756 return da8xx_ddr2_ctlr_base;
757} 757}
@@ -832,7 +832,7 @@ static struct resource da8xx_spi1_resources[] = {
832 }, 832 },
833}; 833};
834 834
835struct davinci_spi_platform_data da8xx_spi_pdata[] = { 835static struct davinci_spi_platform_data da8xx_spi_pdata[] = {
836 [0] = { 836 [0] = {
837 .version = SPI_VERSION_2, 837 .version = SPI_VERSION_2,
838 .intr_line = 1, 838 .intr_line = 1,
@@ -866,20 +866,12 @@ static struct platform_device da8xx_spi_device[] = {
866 }, 866 },
867}; 867};
868 868
869int __init da8xx_register_spi(int instance, const struct spi_board_info *info, 869int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
870 unsigned len)
871{ 870{
872 int ret;
873
874 if (instance < 0 || instance > 1) 871 if (instance < 0 || instance > 1)
875 return -EINVAL; 872 return -EINVAL;
876 873
877 ret = spi_register_board_info(info, len); 874 da8xx_spi_pdata[instance].num_chipselect = num_chipselect;
878 if (ret)
879 pr_warning("%s: failed to register board info for spi %d :"
880 " %d\n", __func__, instance, ret);
881
882 da8xx_spi_pdata[instance].num_chipselect = len;
883 875
884 if (instance == 1 && cpu_is_davinci_da850()) { 876 if (instance == 1 && cpu_is_davinci_da850()) {
885 da8xx_spi1_resources[0].start = DA850_SPI1_BASE; 877 da8xx_spi1_resources[0].start = DA850_SPI1_BASE;
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h
index a3b040219876..3e8af6a0b64c 100644
--- a/arch/arm/mach-davinci/include/mach/clock.h
+++ b/arch/arm/mach-davinci/include/mach/clock.h
@@ -18,4 +18,7 @@ struct clk;
18extern int clk_register(struct clk *clk); 18extern int clk_register(struct clk *clk);
19extern void clk_unregister(struct clk *clk); 19extern void clk_unregister(struct clk *clk);
20 20
21int davinci_clk_reset_assert(struct clk *c);
22int davinci_clk_reset_deassert(struct clk *c);
23
21#endif 24#endif
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 700d311c6854..1b14aea40310 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -82,8 +82,7 @@ void __init da850_init(void);
82int da830_register_edma(struct edma_rsv_info *rsv); 82int da830_register_edma(struct edma_rsv_info *rsv);
83int da850_register_edma(struct edma_rsv_info *rsv[2]); 83int da850_register_edma(struct edma_rsv_info *rsv[2]);
84int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata); 84int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
85int da8xx_register_spi(int instance, 85int da8xx_register_spi_bus(int instance, unsigned num_chipselect);
86 const struct spi_board_info *info, unsigned len);
87int da8xx_register_watchdog(void); 86int da8xx_register_watchdog(void);
88int da8xx_register_usb20(unsigned mA, unsigned potpgt); 87int da8xx_register_usb20(unsigned mA, unsigned potpgt);
89int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata); 88int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
@@ -110,7 +109,6 @@ extern struct platform_device da8xx_serial_device;
110extern struct emac_platform_data da8xx_emac_pdata; 109extern struct emac_platform_data da8xx_emac_pdata;
111extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata; 110extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata;
112extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata; 111extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata;
113extern struct davinci_spi_platform_data da8xx_spi_pdata[];
114 112
115extern struct platform_device da8xx_wdt_device; 113extern struct platform_device da8xx_wdt_device;
116 114
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
index 40a0027838e8..0a22710493fd 100644
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -246,6 +246,7 @@
246 246
247#define MDSTAT_STATE_MASK 0x3f 247#define MDSTAT_STATE_MASK 0x3f
248#define PDSTAT_STATE_MASK 0x1f 248#define PDSTAT_STATE_MASK 0x1f
249#define MDCTL_LRST BIT(8)
249#define MDCTL_FORCE BIT(31) 250#define MDCTL_FORCE BIT(31)
250#define PDCTL_NEXT BIT(0) 251#define PDCTL_NEXT BIT(0)
251#define PDCTL_EPCGOOD BIT(8) 252#define PDCTL_EPCGOOD BIT(8)
@@ -253,6 +254,8 @@
253#ifndef __ASSEMBLER__ 254#ifndef __ASSEMBLER__
254 255
255extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); 256extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
257extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
258 bool reset);
256extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, 259extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
257 unsigned int id, bool enable, u32 flags); 260 unsigned int id, bool enable, u32 flags);
258 261
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
index d7e210f4b55c..82fdc69d5728 100644
--- a/arch/arm/mach-davinci/psc.c
+++ b/arch/arm/mach-davinci/psc.c
@@ -35,7 +35,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
35 struct davinci_soc_info *soc_info = &davinci_soc_info; 35 struct davinci_soc_info *soc_info = &davinci_soc_info;
36 36
37 if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { 37 if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
38 pr_warning("PSC: Bad psc data: 0x%x[%d]\n", 38 pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
39 (int)soc_info->psc_bases, ctlr); 39 (int)soc_info->psc_bases, ctlr);
40 return 0; 40 return 0;
41 } 41 }
@@ -48,6 +48,31 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
48 return mdstat & BIT(12); 48 return mdstat & BIT(12);
49} 49}
50 50
51/* Control "reset" line associated with PSC domain */
52void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
53{
54 u32 mdctl;
55 void __iomem *psc_base;
56 struct davinci_soc_info *soc_info = &davinci_soc_info;
57
58 if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
59 pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
60 (int)soc_info->psc_bases, ctlr);
61 return;
62 }
63
64 psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
65
66 mdctl = readl(psc_base + MDCTL + 4 * id);
67 if (reset)
68 mdctl &= ~MDCTL_LRST;
69 else
70 mdctl |= MDCTL_LRST;
71 writel(mdctl, psc_base + MDCTL + 4 * id);
72
73 iounmap(psc_base);
74}
75
51/* Enable or disable a PSC domain */ 76/* Enable or disable a PSC domain */
52void davinci_psc_config(unsigned int domain, unsigned int ctlr, 77void davinci_psc_config(unsigned int domain, unsigned int ctlr,
53 unsigned int id, bool enable, u32 flags) 78 unsigned int id, bool enable, u32 flags)
@@ -58,7 +83,7 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr,
58 u32 next_state = PSC_STATE_ENABLE; 83 u32 next_state = PSC_STATE_ENABLE;
59 84
60 if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { 85 if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
61 pr_warning("PSC: Bad psc data: 0x%x[%d]\n", 86 pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
62 (int)soc_info->psc_bases, ctlr); 87 (int)soc_info->psc_bases, ctlr);
63 return; 88 return;
64 } 89 }
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 240e0294c372..c4ce0906d76a 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -28,7 +28,11 @@ obj-$(CONFIG_MXC_ULPI) += ulpi.o
28obj-$(CONFIG_MXC_USE_EPIT) += epit.o 28obj-$(CONFIG_MXC_USE_EPIT) += epit.o
29obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o 29obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
30obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o 30obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
31obj-$(CONFIG_CPU_IDLE) += cpuidle.o 31
32ifeq ($(CONFIG_CPU_IDLE),y)
33obj-y += cpuidle.o
34obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
35endif
32 36
33ifdef CONFIG_SND_IMX_SOC 37ifdef CONFIG_SND_IMX_SOC
34obj-y += ssi-fiq.o 38obj-y += ssi-fiq.o
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index e30369a58e4e..30b3242a7d49 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -62,7 +62,7 @@ static const char *clko_sel_clks[] = {
62 "32k", "usb_div", "dptc", 62 "32k", "usb_div", "dptc",
63}; 63};
64 64
65static const char *ssi_sel_clks[] = { "spll", "mpll", }; 65static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };
66 66
67enum mx27_clks { 67enum mx27_clks {
68 dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div, 68 dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
@@ -82,7 +82,7 @@ enum mx27_clks {
82 csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate, 82 csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
83 uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate, 83 uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
84 uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel, 84 uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel,
85 mpll_sel, clk_max 85 mpll_sel, spll_gate, clk_max
86}; 86};
87 87
88static struct clk *clk[clk_max]; 88static struct clk *clk[clk_max];
@@ -104,6 +104,7 @@ int __init mx27_clocks_init(unsigned long fref)
104 ARRAY_SIZE(mpll_sel_clks)); 104 ARRAY_SIZE(mpll_sel_clks));
105 clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); 105 clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
106 clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0); 106 clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0);
107 clk[spll_gate] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
107 clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3); 108 clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
108 109
109 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { 110 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
@@ -121,7 +122,7 @@ int __init mx27_clocks_init(unsigned long fref)
121 clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6); 122 clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
122 clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks)); 123 clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
123 clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6); 124 clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6);
124 clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3); 125 clk[usb_div] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 28, 3);
125 clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); 126 clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
126 clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); 127 clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
127 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) 128 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
index 16ccbd41dea9..b5b65f3efaf1 100644
--- a/arch/arm/mach-imx/clk-imx31.c
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -34,8 +34,8 @@ static const char *csi_sel[] = { "upll", "spll", };
34static const char *fir_sel[] = { "mcu_main", "upll", "spll" }; 34static const char *fir_sel[] = { "mcu_main", "upll", "spll" };
35 35
36enum mx31_clks { 36enum mx31_clks {
37 ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div, 37 dummy, ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg,
38 per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre, 38 per_div, per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
39 fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate, 39 fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
40 iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate, 40 iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
41 uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate, 41 uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
@@ -46,12 +46,15 @@ enum mx31_clks {
46}; 46};
47 47
48static struct clk *clk[clk_max]; 48static struct clk *clk[clk_max];
49static struct clk_onecell_data clk_data;
49 50
50int __init mx31_clocks_init(unsigned long fref) 51int __init mx31_clocks_init(unsigned long fref)
51{ 52{
52 void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); 53 void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
53 int i; 54 int i;
55 struct device_node *np;
54 56
57 clk[dummy] = imx_clk_fixed("dummy", 0);
55 clk[ckih] = imx_clk_fixed("ckih", fref); 58 clk[ckih] = imx_clk_fixed("ckih", fref);
56 clk[ckil] = imx_clk_fixed("ckil", 32768); 59 clk[ckil] = imx_clk_fixed("ckil", 32768);
57 clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL); 60 clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
@@ -116,6 +119,14 @@ int __init mx31_clocks_init(unsigned long fref)
116 pr_err("imx31 clk %d: register failed with %ld\n", 119 pr_err("imx31 clk %d: register failed with %ld\n",
117 i, PTR_ERR(clk[i])); 120 i, PTR_ERR(clk[i]));
118 121
122 np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
123
124 if (np) {
125 clk_data.clks = clk;
126 clk_data.clk_num = ARRAY_SIZE(clk);
127 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
128 }
129
119 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); 130 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
120 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); 131 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
121 clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0"); 132 clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0");
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
index f0727e80815d..74e3a34d78b8 100644
--- a/arch/arm/mach-imx/clk-imx35.c
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -67,13 +67,13 @@ enum mx35_clks {
67 67
68static struct clk *clk[clk_max]; 68static struct clk *clk[clk_max];
69 69
70int __init mx35_clocks_init() 70int __init mx35_clocks_init(void)
71{ 71{
72 void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); 72 void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
73 u32 pdr0, consumer_sel, hsp_sel; 73 u32 pdr0, consumer_sel, hsp_sel;
74 struct arm_ahb_div *aad; 74 struct arm_ahb_div *aad;
75 unsigned char *hsp_div; 75 unsigned char *hsp_div;
76 int i; 76 u32 i;
77 77
78 pdr0 = __raw_readl(base + MXC_CCM_PDR0); 78 pdr0 = __raw_readl(base + MXC_CCM_PDR0);
79 consumer_sel = (pdr0 >> 16) & 0xf; 79 consumer_sel = (pdr0 >> 16) & 0xf;
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 19644f6524dc..540138c4606c 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -54,8 +54,19 @@
54#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) 54#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
55#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) 55#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
56 56
57#define CGPR 0x64
58#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
59
57static void __iomem *ccm_base; 60static void __iomem *ccm_base;
58 61
62void imx6q_set_chicken_bit(void)
63{
64 u32 val = readl_relaxed(ccm_base + CGPR);
65
66 val |= BM_CGPR_CHICKEN_BIT;
67 writel_relaxed(val, ccm_base + CGPR);
68}
69
59int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) 70int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
60{ 71{
61 u32 val = readl_relaxed(ccm_base + CLPCR); 72 u32 val = readl_relaxed(ccm_base + CLPCR);
@@ -66,6 +77,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
66 break; 77 break;
67 case WAIT_UNCLOCKED: 78 case WAIT_UNCLOCKED:
68 val |= 0x1 << BP_CLPCR_LPM; 79 val |= 0x1 << BP_CLPCR_LPM;
80 val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
69 break; 81 break;
70 case STOP_POWER_ON: 82 case STOP_POWER_ON:
71 val |= 0x2 << BP_CLPCR_LPM; 83 val |= 0x2 << BP_CLPCR_LPM;
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 76c420043289..5a800bfcec5b 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -116,9 +116,11 @@ extern u32 *pl310_get_save_ptr(void);
116extern void v7_secondary_startup(void); 116extern void v7_secondary_startup(void);
117extern void imx_scu_map_io(void); 117extern void imx_scu_map_io(void);
118extern void imx_smp_prepare(void); 118extern void imx_smp_prepare(void);
119extern void imx_scu_standby_enable(void);
119#else 120#else
120static inline void imx_scu_map_io(void) {} 121static inline void imx_scu_map_io(void) {}
121static inline void imx_smp_prepare(void) {} 122static inline void imx_smp_prepare(void) {}
123static inline void imx_scu_standby_enable(void) {}
122#endif 124#endif
123extern void imx_enable_cpu(int cpu, bool enable); 125extern void imx_enable_cpu(int cpu, bool enable);
124extern void imx_set_cpu_jump(int cpu, void *jump_addr); 126extern void imx_set_cpu_jump(int cpu, void *jump_addr);
@@ -128,6 +130,7 @@ extern void imx_gpc_init(void);
128extern void imx_gpc_pre_suspend(void); 130extern void imx_gpc_pre_suspend(void);
129extern void imx_gpc_post_resume(void); 131extern void imx_gpc_post_resume(void);
130extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); 132extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
133extern void imx6q_set_chicken_bit(void);
131 134
132extern void imx_cpu_die(unsigned int cpu); 135extern void imx_cpu_die(unsigned int cpu);
133extern int imx_cpu_kill(unsigned int cpu); 136extern int imx_cpu_kill(unsigned int cpu);
diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c
new file mode 100644
index 000000000000..d533e2695f0e
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6q.c
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2012 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clockchips.h>
10#include <linux/cpuidle.h>
11#include <linux/module.h>
12#include <asm/cpuidle.h>
13#include <asm/proc-fns.h>
14
15#include "common.h"
16#include "cpuidle.h"
17
18static atomic_t master = ATOMIC_INIT(0);
19static DEFINE_SPINLOCK(master_lock);
20
21static int imx6q_enter_wait(struct cpuidle_device *dev,
22 struct cpuidle_driver *drv, int index)
23{
24 int cpu = dev->cpu;
25
26 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
27
28 if (atomic_inc_return(&master) == num_online_cpus()) {
29 /*
30 * With this lock, we prevent other cpu to exit and enter
31 * this function again and become the master.
32 */
33 if (!spin_trylock(&master_lock))
34 goto idle;
35 imx6q_set_lpm(WAIT_UNCLOCKED);
36 cpu_do_idle();
37 imx6q_set_lpm(WAIT_CLOCKED);
38 spin_unlock(&master_lock);
39 goto done;
40 }
41
42idle:
43 cpu_do_idle();
44done:
45 atomic_dec(&master);
46 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
47
48 return index;
49}
50
51/*
52 * For each cpu, setup the broadcast timer because local timer
53 * stops for the states other than WFI.
54 */
55static void imx6q_setup_broadcast_timer(void *arg)
56{
57 int cpu = smp_processor_id();
58
59 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
60}
61
62static struct cpuidle_driver imx6q_cpuidle_driver = {
63 .name = "imx6q_cpuidle",
64 .owner = THIS_MODULE,
65 .en_core_tk_irqen = 1,
66 .states = {
67 /* WFI */
68 ARM_CPUIDLE_WFI_STATE,
69 /* WAIT */
70 {
71 .exit_latency = 50,
72 .target_residency = 75,
73 .flags = CPUIDLE_FLAG_TIME_VALID,
74 .enter = imx6q_enter_wait,
75 .name = "WAIT",
76 .desc = "Clock off",
77 },
78 },
79 .state_count = 2,
80 .safe_state_index = 0,
81};
82
83int __init imx6q_cpuidle_init(void)
84{
85 /* Need to enable SCU standby for entering WAIT modes */
86 imx_scu_standby_enable();
87
88 /* Set chicken bit to get a reliable WAIT mode support */
89 imx6q_set_chicken_bit();
90
91 /* Configure the broadcast timer on each cpu */
92 on_each_cpu(imx6q_setup_broadcast_timer, NULL, 1);
93
94 return imx_cpuidle_init(&imx6q_cpuidle_driver);
95}
diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
index bc932d1af372..e092d1359d94 100644
--- a/arch/arm/mach-imx/cpuidle.h
+++ b/arch/arm/mach-imx/cpuidle.h
@@ -14,9 +14,14 @@
14 14
15#ifdef CONFIG_CPU_IDLE 15#ifdef CONFIG_CPU_IDLE
16extern int imx_cpuidle_init(struct cpuidle_driver *drv); 16extern int imx_cpuidle_init(struct cpuidle_driver *drv);
17extern int imx6q_cpuidle_init(void);
17#else 18#else
18static inline int imx_cpuidle_init(struct cpuidle_driver *drv) 19static inline int imx_cpuidle_init(struct cpuidle_driver *drv)
19{ 20{
20 return -ENODEV; 21 return -ENODEV;
21} 22}
23static inline int imx6q_cpuidle_init(void)
24{
25 return -ENODEV;
26}
22#endif 27#endif
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index ff24920699e4..a96ccc7f5012 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -101,11 +101,16 @@ static void imx_gpc_irq_mask(struct irq_data *d)
101void __init imx_gpc_init(void) 101void __init imx_gpc_init(void)
102{ 102{
103 struct device_node *np; 103 struct device_node *np;
104 int i;
104 105
105 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc"); 106 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
106 gpc_base = of_iomap(np, 0); 107 gpc_base = of_iomap(np, 0);
107 WARN_ON(!gpc_base); 108 WARN_ON(!gpc_base);
108 109
110 /* Initially mask all interrupts */
111 for (i = 0; i < IMR_NUM; i++)
112 writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
113
109 /* Register GPC as the secondary interrupt controller behind GIC */ 114 /* Register GPC as the secondary interrupt controller behind GIC */
110 gic_arch_extn.irq_mask = imx_gpc_irq_mask; 115 gic_arch_extn.irq_mask = imx_gpc_irq_mask;
111 gic_arch_extn.irq_unmask = imx_gpc_irq_unmask; 116 gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S
index 7e49deb128a4..921fc1555854 100644
--- a/arch/arm/mach-imx/headsmp.S
+++ b/arch/arm/mach-imx/headsmp.S
@@ -17,53 +17,6 @@
17 17
18 .section ".text.head", "ax" 18 .section ".text.head", "ax"
19 19
20/*
21 * The secondary kernel init calls v7_flush_dcache_all before it enables
22 * the L1; however, the L1 comes out of reset in an undefined state, so
23 * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
24 * of cache lines with uninitialized data and uninitialized tags to get
25 * written out to memory, which does really unpleasant things to the main
26 * processor. We fix this by performing an invalidate, rather than a
27 * clean + invalidate, before jumping into the kernel.
28 *
29 * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
30 * to be called for both secondary cores startup and primary core resume
31 * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
32 */
33ENTRY(v7_invalidate_l1)
34 mov r0, #0
35 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
36 mcr p15, 2, r0, c0, c0, 0
37 mrc p15, 1, r0, c0, c0, 0
38
39 ldr r1, =0x7fff
40 and r2, r1, r0, lsr #13
41
42 ldr r1, =0x3ff
43
44 and r3, r1, r0, lsr #3 @ NumWays - 1
45 add r2, r2, #1 @ NumSets
46
47 and r0, r0, #0x7
48 add r0, r0, #4 @ SetShift
49
50 clz r1, r3 @ WayShift
51 add r4, r3, #1 @ NumWays
521: sub r2, r2, #1 @ NumSets--
53 mov r3, r4 @ Temp = NumWays
542: subs r3, r3, #1 @ Temp--
55 mov r5, r3, lsl r1
56 mov r6, r2, lsl r0
57 orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
58 mcr p15, 0, r5, c7, c6, 2
59 bgt 2b
60 cmp r2, #0
61 bgt 1b
62 dsb
63 isb
64 mov pc, lr
65ENDPROC(v7_invalidate_l1)
66
67#ifdef CONFIG_SMP 20#ifdef CONFIG_SMP
68ENTRY(v7_secondary_startup) 21ENTRY(v7_secondary_startup)
69 bl v7_invalidate_l1 22 bl v7_invalidate_l1
diff --git a/arch/arm/mach-imx/imx31-dt.c b/arch/arm/mach-imx/imx31-dt.c
index b5c04eece780..67de611e29ab 100644
--- a/arch/arm/mach-imx/imx31-dt.c
+++ b/arch/arm/mach-imx/imx31-dt.c
@@ -18,24 +18,9 @@
18#include "common.h" 18#include "common.h"
19#include "mx31.h" 19#include "mx31.h"
20 20
21static const struct of_dev_auxdata imx31_auxdata_lookup[] __initconst = {
22 OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART1_BASE_ADDR,
23 "imx21-uart.0", NULL),
24 OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART2_BASE_ADDR,
25 "imx21-uart.1", NULL),
26 OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART3_BASE_ADDR,
27 "imx21-uart.2", NULL),
28 OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART4_BASE_ADDR,
29 "imx21-uart.3", NULL),
30 OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART5_BASE_ADDR,
31 "imx21-uart.4", NULL),
32 { /* sentinel */ }
33};
34
35static void __init imx31_dt_init(void) 21static void __init imx31_dt_init(void)
36{ 22{
37 of_platform_populate(NULL, of_default_bus_match_table, 23 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
38 imx31_auxdata_lookup, NULL);
39} 24}
40 25
41static const char *imx31_dt_board_compat[] __initdata = { 26static const char *imx31_dt_board_compat[] __initdata = {
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 5a18e7e5c564..1786b2d1257e 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -12,7 +12,6 @@
12 12
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/clkdev.h> 14#include <linux/clkdev.h>
15#include <linux/cpuidle.h>
16#include <linux/delay.h> 15#include <linux/delay.h>
17#include <linux/export.h> 16#include <linux/export.h>
18#include <linux/init.h> 17#include <linux/init.h>
@@ -27,7 +26,6 @@
27#include <linux/regmap.h> 26#include <linux/regmap.h>
28#include <linux/micrel_phy.h> 27#include <linux/micrel_phy.h>
29#include <linux/mfd/syscon.h> 28#include <linux/mfd/syscon.h>
30#include <asm/cpuidle.h>
31#include <asm/smp_twd.h> 29#include <asm/smp_twd.h>
32#include <asm/hardware/cache-l2x0.h> 30#include <asm/hardware/cache-l2x0.h>
33#include <asm/mach/arch.h> 31#include <asm/mach/arch.h>
@@ -202,17 +200,14 @@ static void __init imx6q_init_machine(void)
202 imx6q_1588_init(); 200 imx6q_1588_init();
203} 201}
204 202
205static struct cpuidle_driver imx6q_cpuidle_driver = {
206 .name = "imx6q_cpuidle",
207 .owner = THIS_MODULE,
208 .en_core_tk_irqen = 1,
209 .states[0] = ARM_CPUIDLE_WFI_STATE,
210 .state_count = 1,
211};
212
213static void __init imx6q_init_late(void) 203static void __init imx6q_init_late(void)
214{ 204{
215 imx_cpuidle_init(&imx6q_cpuidle_driver); 205 /*
206 * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
207 * to run cpuidle on them.
208 */
209 if (imx6q_revision() > IMX_CHIP_REVISION_1_1)
210 imx6q_cpuidle_init();
216} 211}
217 212
218static void __init imx6q_map_io(void) 213static void __init imx6q_map_io(void)
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index b2872ec614a4..7c0b03f67b05 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -20,6 +20,8 @@
20#include "common.h" 20#include "common.h"
21#include "hardware.h" 21#include "hardware.h"
22 22
23#define SCU_STANDBY_ENABLE (1 << 5)
24
23static void __iomem *scu_base; 25static void __iomem *scu_base;
24 26
25static struct map_desc scu_io_desc __initdata = { 27static struct map_desc scu_io_desc __initdata = {
@@ -42,6 +44,14 @@ void __init imx_scu_map_io(void)
42 scu_base = IMX_IO_ADDRESS(base); 44 scu_base = IMX_IO_ADDRESS(base);
43} 45}
44 46
47void imx_scu_standby_enable(void)
48{
49 u32 val = readl_relaxed(scu_base);
50
51 val |= SCU_STANDBY_ENABLE;
52 writel_relaxed(val, scu_base);
53}
54
45static void __cpuinit imx_secondary_init(unsigned int cpu) 55static void __cpuinit imx_secondary_init(unsigned int cpu)
46{ 56{
47 /* 57 /*
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 62769df36db1..fea91313678b 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -152,7 +152,8 @@ static int v2_set_next_event(unsigned long evt,
152 152
153 __raw_writel(tcmp, timer_base + V2_TCMP); 153 __raw_writel(tcmp, timer_base + V2_TCMP);
154 154
155 return (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ? 155 return evt < 0x7fffffff &&
156 (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
156 -ETIME : 0; 157 -ETIME : 0;
157} 158}
158 159
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index 8d2e5a96247c..d6653095a1eb 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
19obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o 19obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
20obj-$(CONFIG_MACH_T5325) += t5325-setup.o 20obj-$(CONFIG_MACH_T5325) += t5325-setup.o
21 21
22obj-$(CONFIG_CPU_IDLE) += cpuidle.o
23obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o 22obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o
24obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o 23obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o
25obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o 24obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index d4af5c191c24..95cc04d14b65 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -98,6 +98,8 @@ static void __init kirkwood_dt_init(void)
98 /* Setup root of clk tree */ 98 /* Setup root of clk tree */
99 kirkwood_of_clk_init(); 99 kirkwood_of_clk_init();
100 100
101 kirkwood_cpuidle_init();
102
101#ifdef CONFIG_KEXEC 103#ifdef CONFIG_KEXEC
102 kexec_reinit = kirkwood_enable_pcie; 104 kexec_reinit = kirkwood_enable_pcie;
103#endif 105#endif
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index b5ad4dff6b12..49792a0cd2d3 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -499,6 +499,28 @@ void __init kirkwood_wdt_init(void)
499 orion_wdt_init(); 499 orion_wdt_init();
500} 500}
501 501
502/*****************************************************************************
503 * CPU idle
504 ****************************************************************************/
505static struct resource kirkwood_cpuidle_resource[] = {
506 {
507 .flags = IORESOURCE_MEM,
508 .start = DDR_OPERATION_BASE,
509 .end = DDR_OPERATION_BASE + 3,
510 },
511};
512
513static struct platform_device kirkwood_cpuidle = {
514 .name = "kirkwood_cpuidle",
515 .id = -1,
516 .resource = kirkwood_cpuidle_resource,
517 .num_resources = 1,
518};
519
520void __init kirkwood_cpuidle_init(void)
521{
522 platform_device_register(&kirkwood_cpuidle);
523}
502 524
503/***************************************************************************** 525/*****************************************************************************
504 * Time handling 526 * Time handling
@@ -667,6 +689,7 @@ void __init kirkwood_init(void)
667 kirkwood_xor1_init(); 689 kirkwood_xor1_init();
668 kirkwood_crypto_init(); 690 kirkwood_crypto_init();
669 691
692 kirkwood_cpuidle_init();
670#ifdef CONFIG_KEXEC 693#ifdef CONFIG_KEXEC
671 kexec_reinit = kirkwood_enable_pcie; 694 kexec_reinit = kirkwood_enable_pcie;
672#endif 695#endif
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 283ab611e8da..e956d0277dd1 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -50,6 +50,7 @@ void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay);
50void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, 50void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
51 int (*dev_ready)(struct mtd_info *)); 51 int (*dev_ready)(struct mtd_info *));
52void kirkwood_audio_init(void); 52void kirkwood_audio_init(void);
53void kirkwood_cpuidle_init(void);
53void kirkwood_restart(char, const char *); 54void kirkwood_restart(char, const char *);
54void kirkwood_clk_init(void); 55void kirkwood_clk_init(void);
55 56
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index 041653a04a9c..a05563a31c95 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -60,8 +60,9 @@
60 * Register Map 60 * Register Map
61 */ 61 */
62#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000) 62#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000)
63#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
63#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500) 64#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500)
64#define DDR_OPERATION_BASE (DDR_VIRT_BASE + 0x1418) 65#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418)
65 66
66#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000) 67#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000)
67#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x10000) 68#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x10000)
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index a1c3ab6fc809..d96ad4c09972 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -247,13 +247,9 @@ static struct hw_pci kirkwood_pci __initdata = {
247 247
248static void __init add_pcie_port(int index, void __iomem *base) 248static void __init add_pcie_port(int index, void __iomem *base)
249{ 249{
250 pr_info("Kirkwood PCIe port %d: ", index); 250 pcie_port_map[num_pcie_ports++] = index;
251 251 pr_info("Kirkwood PCIe port %d: link %s\n", index,
252 if (orion_pcie_link_up(base)) { 252 orion_pcie_link_up(base) ? "up" : "down");
253 pr_info("link up\n");
254 pcie_port_map[num_pcie_ports++] = index;
255 } else
256 pr_info("link down, ignoring\n");
257} 253}
258 254
259void __init kirkwood_pcie_init(unsigned int portmask) 255void __init kirkwood_pcie_init(unsigned int portmask)
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
index 27451b1ba3f1..421020498a1b 100644
--- a/arch/arm/mach-mxs/timer.c
+++ b/arch/arm/mach-mxs/timer.c
@@ -72,8 +72,9 @@
72#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14) 72#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
73#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15) 73#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
74#define BP_TIMROT_TIMCTRLn_SELECT 0 74#define BP_TIMROT_TIMCTRLn_SELECT 0
75#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8 75#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
76#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb 76#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
77#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS 0xf
77 78
78static struct clock_event_device mxs_clockevent_device; 79static struct clock_event_device mxs_clockevent_device;
79static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED; 80static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
@@ -206,7 +207,8 @@ static int __init mxs_clockevent_init(struct clk *timer_clk)
206 mxs_clockevent_device.set_next_event = timrotv1_set_next_event; 207 mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
207 mxs_clockevent_device.cpumask = cpumask_of(0); 208 mxs_clockevent_device.cpumask = cpumask_of(0);
208 clockevents_config_and_register(&mxs_clockevent_device, 209 clockevents_config_and_register(&mxs_clockevent_device,
209 clk_get_rate(timer_clk), 0xf, 210 clk_get_rate(timer_clk),
211 timrot_is_v1() ? 0xf : 0x2,
210 timrot_is_v1() ? 0xfffe : 0xfffffffe); 212 timrot_is_v1() ? 0xfffe : 0xfffffffe);
211 213
212 return 0; 214 return 0;
@@ -274,7 +276,7 @@ void __init mxs_timer_init(void)
274 /* one for clock_event */ 276 /* one for clock_event */
275 __raw_writel((timrot_is_v1() ? 277 __raw_writel((timrot_is_v1() ?
276 BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL : 278 BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
277 BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) | 279 BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
278 BM_TIMROT_TIMCTRLn_UPDATE | 280 BM_TIMROT_TIMCTRLn_UPDATE |
279 BM_TIMROT_TIMCTRLn_IRQ_EN, 281 BM_TIMROT_TIMCTRLn_IRQ_EN,
280 mxs_timrot_base + HW_TIMROT_TIMCTRLn(0)); 282 mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
@@ -282,7 +284,7 @@ void __init mxs_timer_init(void)
282 /* another for clocksource */ 284 /* another for clocksource */
283 __raw_writel((timrot_is_v1() ? 285 __raw_writel((timrot_is_v1() ?
284 BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL : 286 BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
285 BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) | 287 BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
286 BM_TIMROT_TIMCTRLn_RELOAD, 288 BM_TIMROT_TIMCTRLn_RELOAD,
287 mxs_timrot_base + HW_TIMROT_TIMCTRLn(1)); 289 mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
288 290
diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
index af11dcdb7e2c..a00d39107a21 100644
--- a/arch/arm/mach-omap2/am35xx-emac.c
+++ b/arch/arm/mach-omap2/am35xx-emac.c
@@ -63,7 +63,7 @@ static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh,
63 struct platform_device *pdev; 63 struct platform_device *pdev;
64 64
65 pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len, 65 pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len,
66 NULL, 0, false); 66 false);
67 if (IS_ERR(pdev)) { 67 if (IS_ERR(pdev)) {
68 WARN(1, "Can't build omap_device for %s:%s.\n", 68 WARN(1, "Can't build omap_device for %s:%s.\n",
69 oh->class->name, oh->name); 69 oh->class->name, oh->name);
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index e71ebdefc679..15a3914ab492 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -425,7 +425,7 @@ static void enable_board_wakeup_source(void)
425 OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); 425 OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
426} 426}
427 427
428static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 428static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
429 429
430 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 430 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
431 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 431 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 33846274bb8a..67447bd4564f 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -53,7 +53,7 @@ static void enable_board_wakeup_source(void)
53 OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); 53 OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
54} 54}
55 55
56static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 56static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
57 57
58 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 58 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
59 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 59 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
index 07f0be24a5d1..52cc2c597314 100644
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -40,7 +40,7 @@ static struct omap_board_mux board_mux[] __initdata = {
40}; 40};
41#endif 41#endif
42 42
43static struct usbhs_omap_board_data usbhs_bdata __initdata = { 43static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
44 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 44 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
45 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, 45 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
46 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 46 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 6f5b2a05f4b2..9fb85908a61e 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -274,7 +274,7 @@ static __init void am3517_evm_mcbsp1_init(void)
274 omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); 274 omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0);
275} 275}
276 276
277static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 277static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
278 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 278 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
279#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ 279#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
280 defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE) 280 defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE)
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 231a7d825f99..10054e3c3482 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -419,7 +419,7 @@ static struct omap2_hsmmc_info mmc[] = {
419 {} /* Terminator */ 419 {} /* Terminator */
420}; 420};
421 421
422static struct usbhs_omap_board_data usbhs_bdata __initdata = { 422static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
423 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 423 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
424 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 424 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
425 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 425 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 6a9529ab95cd..5e54f565a294 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -166,7 +166,7 @@ static inline void cm_t3517_init_rtc(void) {}
166#define HSUSB2_RESET_GPIO (147) 166#define HSUSB2_RESET_GPIO (147)
167#define USB_HUB_RESET_GPIO (152) 167#define USB_HUB_RESET_GPIO (152)
168 168
169static struct usbhs_omap_board_data cm_t3517_ehci_pdata __initdata = { 169static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = {
170 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 170 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
171 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 171 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
172 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 172 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index a37514ecc385..4dadb0b7b808 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -436,7 +436,7 @@ static struct platform_device *devkit8000_devices[] __initdata = {
436 &omap_dm9000_dev, 436 &omap_dm9000_dev,
437}; 437};
438 438
439static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 439static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
440 440
441 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 441 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
442 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, 442 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 3f97f30d788e..c10738a067cd 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -527,7 +527,7 @@ static void __init igep_i2c_init(void)
527 omap3_pmic_init("twl4030", &igep_twldata); 527 omap3_pmic_init("twl4030", &igep_twldata);
528} 528}
529 529
530static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = { 530static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = {
531 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 531 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
532 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, 532 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
533 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 533 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
@@ -538,7 +538,7 @@ static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = {
538 .reset_gpio_port[2] = -EINVAL, 538 .reset_gpio_port[2] = -EINVAL,
539}; 539};
540 540
541static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = { 541static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = {
542 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, 542 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
543 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 543 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
544 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 544 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 284500ddacdb..70bc1fc808c8 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -431,7 +431,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = {
431 &madc_hwmon, 431 &madc_hwmon,
432}; 432};
433 433
434static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 434static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
435 435
436 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, 436 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
437 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 437 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index f43763647d58..8258a78c3dfb 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -539,7 +539,7 @@ static int __init omap3_evm_i2c_init(void)
539 return 0; 539 return 0;
540} 540}
541 541
542static struct usbhs_omap_board_data usbhs_bdata __initdata = { 542static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
543 543
544 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, 544 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
545 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 545 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 07cc0884e761..2bba362148a0 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -568,7 +568,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
568 &pandora_backlight, 568 &pandora_backlight,
569}; 569};
570 570
571static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 571static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
572 572
573 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, 573 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
574 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 574 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 0490acbc4331..95c10b3aa678 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -362,7 +362,7 @@ static struct platform_device *omap3_stalker_devices[] __initdata = {
362 &keys_gpio, 362 &keys_gpio,
363}; 363};
364 364
365static struct usbhs_omap_board_data usbhs_bdata __initconst = { 365static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
366 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, 366 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
367 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 367 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
368 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 368 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 91daf71190cf..bcd44fbcd877 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -310,7 +310,7 @@ static struct platform_device *omap3_touchbook_devices[] __initdata = {
310 &keys_gpio, 310 &keys_gpio,
311}; 311};
312 312
313static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 313static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
314 314
315 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 315 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
316 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 316 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 7b152d04a602..b02c2f00609b 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -140,7 +140,7 @@ static struct platform_device *panda_devices[] __initdata = {
140 &btwilink_device, 140 &btwilink_device,
141}; 141};
142 142
143static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 143static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
144 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 144 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
145 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, 145 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
146 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 146 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 6975a8585dae..1bcf39671c35 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -458,7 +458,7 @@ static int __init overo_spi_init(void)
458 return 0; 458 return 0;
459} 459}
460 460
461static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 461static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
462 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, 462 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
463 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 463 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
464 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 464 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index d257cf1e0abe..5e4d4c9fe61a 100644
--- a/arch/arm/mach-omap2/board-zoom.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -92,7 +92,7 @@ static struct mtd_partition zoom_nand_partitions[] = {
92 }, 92 },
93}; 93};
94 94
95static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 95static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
96 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, 96 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
97 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 97 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
98 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 98 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
diff --git a/arch/arm/mach-omap2/cclock2420_data.c b/arch/arm/mach-omap2/cclock2420_data.c
index ab7e952d2070..0f0a97c1fcc0 100644
--- a/arch/arm/mach-omap2/cclock2420_data.c
+++ b/arch/arm/mach-omap2/cclock2420_data.c
@@ -622,15 +622,10 @@ static struct clk_hw_omap gpios_fck_hw = {
622 622
623DEFINE_STRUCT_CLK(gpios_fck, gpios_fck_parent_names, aes_ick_ops); 623DEFINE_STRUCT_CLK(gpios_fck, gpios_fck_parent_names, aes_ick_ops);
624 624
625static struct clk wu_l4_ick;
626
627DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm");
628DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops);
629
630static struct clk gpios_ick; 625static struct clk gpios_ick;
631 626
632static const char *gpios_ick_parent_names[] = { 627static const char *gpios_ick_parent_names[] = {
633 "wu_l4_ick", 628 "sys_ck",
634}; 629};
635 630
636static struct clk_hw_omap gpios_ick_hw = { 631static struct clk_hw_omap gpios_ick_hw = {
@@ -1682,13 +1677,6 @@ static struct clk_hw_omap wdt1_ick_hw = {
1682 1677
1683DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); 1678DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops);
1684 1679
1685static struct clk wdt1_osc_ck;
1686
1687static const struct clk_ops wdt1_osc_ck_ops = {};
1688
1689DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL);
1690DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops);
1691
1692static struct clk wdt3_fck; 1680static struct clk wdt3_fck;
1693 1681
1694static struct clk_hw_omap wdt3_fck_hw = { 1682static struct clk_hw_omap wdt3_fck_hw = {
@@ -1767,7 +1755,6 @@ static struct omap_clk omap2420_clks[] = {
1767 CLK(NULL, "func_96m_ck", &func_96m_ck, CK_242X), 1755 CLK(NULL, "func_96m_ck", &func_96m_ck, CK_242X),
1768 CLK(NULL, "func_48m_ck", &func_48m_ck, CK_242X), 1756 CLK(NULL, "func_48m_ck", &func_48m_ck, CK_242X),
1769 CLK(NULL, "func_12m_ck", &func_12m_ck, CK_242X), 1757 CLK(NULL, "func_12m_ck", &func_12m_ck, CK_242X),
1770 CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_242X),
1771 CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_242X), 1758 CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_242X),
1772 CLK(NULL, "sys_clkout", &sys_clkout, CK_242X), 1759 CLK(NULL, "sys_clkout", &sys_clkout, CK_242X),
1773 CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X), 1760 CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X),
@@ -1797,7 +1784,6 @@ static struct omap_clk omap2420_clks[] = {
1797 /* L4 domain clocks */ 1784 /* L4 domain clocks */
1798 CLK(NULL, "l4_ck", &l4_ck, CK_242X), 1785 CLK(NULL, "l4_ck", &l4_ck, CK_242X),
1799 CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X), 1786 CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X),
1800 CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_242X),
1801 /* virtual meta-group clock */ 1787 /* virtual meta-group clock */
1802 CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X), 1788 CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X),
1803 /* general l4 interface ck, multi-parent functional clk */ 1789 /* general l4 interface ck, multi-parent functional clk */
diff --git a/arch/arm/mach-omap2/cclock2430_data.c b/arch/arm/mach-omap2/cclock2430_data.c
index eb3dab68d536..aed8f74ca076 100644
--- a/arch/arm/mach-omap2/cclock2430_data.c
+++ b/arch/arm/mach-omap2/cclock2430_data.c
@@ -601,15 +601,10 @@ static struct clk_hw_omap gpios_fck_hw = {
601 601
602DEFINE_STRUCT_CLK(gpios_fck, gpio5_fck_parent_names, aes_ick_ops); 602DEFINE_STRUCT_CLK(gpios_fck, gpio5_fck_parent_names, aes_ick_ops);
603 603
604static struct clk wu_l4_ick;
605
606DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm");
607DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops);
608
609static struct clk gpios_ick; 604static struct clk gpios_ick;
610 605
611static const char *gpios_ick_parent_names[] = { 606static const char *gpios_ick_parent_names[] = {
612 "wu_l4_ick", 607 "sys_ck",
613}; 608};
614 609
615static struct clk_hw_omap gpios_ick_hw = { 610static struct clk_hw_omap gpios_ick_hw = {
@@ -1811,13 +1806,6 @@ static struct clk_hw_omap wdt1_ick_hw = {
1811 1806
1812DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); 1807DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops);
1813 1808
1814static struct clk wdt1_osc_ck;
1815
1816static const struct clk_ops wdt1_osc_ck_ops = {};
1817
1818DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL);
1819DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops);
1820
1821static struct clk wdt4_fck; 1809static struct clk wdt4_fck;
1822 1810
1823static struct clk_hw_omap wdt4_fck_hw = { 1811static struct clk_hw_omap wdt4_fck_hw = {
@@ -1869,7 +1857,6 @@ static struct omap_clk omap2430_clks[] = {
1869 CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X), 1857 CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X),
1870 CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X), 1858 CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X),
1871 CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X), 1859 CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X),
1872 CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_243X),
1873 CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X), 1860 CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X),
1874 CLK(NULL, "sys_clkout", &sys_clkout, CK_243X), 1861 CLK(NULL, "sys_clkout", &sys_clkout, CK_243X),
1875 CLK(NULL, "emul_ck", &emul_ck, CK_243X), 1862 CLK(NULL, "emul_ck", &emul_ck, CK_243X),
@@ -1898,7 +1885,6 @@ static struct omap_clk omap2430_clks[] = {
1898 /* L4 domain clocks */ 1885 /* L4 domain clocks */
1899 CLK(NULL, "l4_ck", &l4_ck, CK_243X), 1886 CLK(NULL, "l4_ck", &l4_ck, CK_243X),
1900 CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X), 1887 CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X),
1901 CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_243X),
1902 /* virtual meta-group clock */ 1888 /* virtual meta-group clock */
1903 CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X), 1889 CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X),
1904 /* general l4 interface ck, multi-parent functional clk */ 1890 /* general l4 interface ck, multi-parent functional clk */
diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c
index a2cc046b47f4..cebe2b31943e 100644
--- a/arch/arm/mach-omap2/cclock44xx_data.c
+++ b/arch/arm/mach-omap2/cclock44xx_data.c
@@ -16,6 +16,10 @@
16 * XXX Some of the ES1 clocks have been removed/changed; once support 16 * XXX Some of the ES1 clocks have been removed/changed; once support
17 * is added for discriminating clocks by ES level, these should be added back 17 * is added for discriminating clocks by ES level, these should be added back
18 * in. 18 * in.
19 *
20 * XXX All of the remaining MODULEMODE clock nodes should be removed
21 * once the drivers are updated to use pm_runtime or to use the appropriate
22 * upstream clock node for rate/parent selection.
19 */ 23 */
20 24
21#include <linux/kernel.h> 25#include <linux/kernel.h>
@@ -315,7 +319,7 @@ DEFINE_CLK_DIVIDER(dpll_abe_m2_ck, "dpll_abe_ck", &dpll_abe_ck, 0x0,
315 OMAP4430_CM_DIV_M2_DPLL_ABE, OMAP4430_DPLL_CLKOUT_DIV_SHIFT, 319 OMAP4430_CM_DIV_M2_DPLL_ABE, OMAP4430_DPLL_CLKOUT_DIV_SHIFT,
316 OMAP4430_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); 320 OMAP4430_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
317 321
318static const struct clk_ops dmic_fck_ops = { 322static const struct clk_ops dpll_hsd_ops = {
319 .enable = &omap2_dflt_clk_enable, 323 .enable = &omap2_dflt_clk_enable,
320 .disable = &omap2_dflt_clk_disable, 324 .disable = &omap2_dflt_clk_disable,
321 .is_enabled = &omap2_dflt_clk_is_enabled, 325 .is_enabled = &omap2_dflt_clk_is_enabled,
@@ -325,6 +329,12 @@ static const struct clk_ops dmic_fck_ops = {
325 .init = &omap2_init_clk_clkdm, 329 .init = &omap2_init_clk_clkdm,
326}; 330};
327 331
332static const struct clk_ops func_dmic_abe_gfclk_ops = {
333 .recalc_rate = &omap2_clksel_recalc,
334 .get_parent = &omap2_clksel_find_parent_index,
335 .set_parent = &omap2_clksel_set_parent,
336};
337
328static const char *dpll_core_m3x2_ck_parents[] = { 338static const char *dpll_core_m3x2_ck_parents[] = {
329 "dpll_core_x2_ck", 339 "dpll_core_x2_ck",
330}; 340};
@@ -340,7 +350,7 @@ DEFINE_CLK_OMAP_MUX_GATE(dpll_core_m3x2_ck, NULL, dpll_core_m3x2_div,
340 OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, 350 OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
341 OMAP4430_CM_DIV_M3_DPLL_CORE, 351 OMAP4430_CM_DIV_M3_DPLL_CORE,
342 OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL, 352 OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL,
343 dpll_core_m3x2_ck_parents, dmic_fck_ops); 353 dpll_core_m3x2_ck_parents, dpll_hsd_ops);
344 354
345DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m7x2_ck, "dpll_core_x2_ck", 355DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m7x2_ck, "dpll_core_x2_ck",
346 &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M7_DPLL_CORE, 356 &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M7_DPLL_CORE,
@@ -547,7 +557,7 @@ DEFINE_CLK_OMAP_MUX_GATE(dpll_per_m3x2_ck, NULL, dpll_per_m3x2_div,
547 OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, 557 OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
548 OMAP4430_CM_DIV_M3_DPLL_PER, 558 OMAP4430_CM_DIV_M3_DPLL_PER,
549 OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL, 559 OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL,
550 dpll_per_m3x2_ck_parents, dmic_fck_ops); 560 dpll_per_m3x2_ck_parents, dpll_hsd_ops);
551 561
552DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m4x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck, 562DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m4x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,
553 0x0, OMAP4430_CM_DIV_M4_DPLL_PER, 563 0x0, OMAP4430_CM_DIV_M4_DPLL_PER,
@@ -749,10 +759,6 @@ DEFINE_CLK_GATE(aes2_fck, "l3_div_ck", &l3_div_ck, 0x0,
749 OMAP4430_CM_L4SEC_AES2_CLKCTRL, 759 OMAP4430_CM_L4SEC_AES2_CLKCTRL,
750 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); 760 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
751 761
752DEFINE_CLK_GATE(aess_fck, "aess_fclk", &aess_fclk, 0x0,
753 OMAP4430_CM1_ABE_AESS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
754 0x0, NULL);
755
756DEFINE_CLK_GATE(bandgap_fclk, "sys_32k_ck", &sys_32k_ck, 0x0, 762DEFINE_CLK_GATE(bandgap_fclk, "sys_32k_ck", &sys_32k_ck, 0x0,
757 OMAP4430_CM_WKUP_BANDGAP_CLKCTRL, 763 OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
758 OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT, 0x0, NULL); 764 OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT, 0x0, NULL);
@@ -774,11 +780,6 @@ DEFINE_CLK_GATE(bandgap_ts_fclk, "div_ts_ck", &div_ts_ck, 0x0,
774 OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT, 780 OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT,
775 0x0, NULL); 781 0x0, NULL);
776 782
777DEFINE_CLK_GATE(des3des_fck, "l4_div_ck", &l4_div_ck, 0x0,
778 OMAP4430_CM_L4SEC_DES3DES_CLKCTRL,
779 OMAP4430_MODULEMODE_SWCTRL_SHIFT,
780 0x0, NULL);
781
782static const char *dmic_sync_mux_ck_parents[] = { 783static const char *dmic_sync_mux_ck_parents[] = {
783 "abe_24m_fclk", "syc_clk_div_ck", "func_24m_clk", 784 "abe_24m_fclk", "syc_clk_div_ck", "func_24m_clk",
784}; 785};
@@ -795,23 +796,13 @@ static const struct clksel func_dmic_abe_gfclk_sel[] = {
795 { .parent = NULL }, 796 { .parent = NULL },
796}; 797};
797 798
798static const char *dmic_fck_parents[] = { 799static const char *func_dmic_abe_gfclk_parents[] = {
799 "dmic_sync_mux_ck", "pad_clks_ck", "slimbus_clk", 800 "dmic_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
800}; 801};
801 802
802/* Merged func_dmic_abe_gfclk into dmic */ 803DEFINE_CLK_OMAP_MUX(func_dmic_abe_gfclk, "abe_clkdm", func_dmic_abe_gfclk_sel,
803static struct clk dmic_fck; 804 OMAP4430_CM1_ABE_DMIC_CLKCTRL, OMAP4430_CLKSEL_SOURCE_MASK,
804 805 func_dmic_abe_gfclk_parents, func_dmic_abe_gfclk_ops);
805DEFINE_CLK_OMAP_MUX_GATE(dmic_fck, "abe_clkdm", func_dmic_abe_gfclk_sel,
806 OMAP4430_CM1_ABE_DMIC_CLKCTRL,
807 OMAP4430_CLKSEL_SOURCE_MASK,
808 OMAP4430_CM1_ABE_DMIC_CLKCTRL,
809 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
810 dmic_fck_parents, dmic_fck_ops);
811
812DEFINE_CLK_GATE(dsp_fck, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, 0x0,
813 OMAP4430_CM_TESLA_TESLA_CLKCTRL,
814 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
815 806
816DEFINE_CLK_GATE(dss_sys_clk, "syc_clk_div_ck", &syc_clk_div_ck, 0x0, 807DEFINE_CLK_GATE(dss_sys_clk, "syc_clk_div_ck", &syc_clk_div_ck, 0x0,
817 OMAP4430_CM_DSS_DSS_CLKCTRL, 808 OMAP4430_CM_DSS_DSS_CLKCTRL,
@@ -833,177 +824,57 @@ DEFINE_CLK_GATE(dss_fck, "l3_div_ck", &l3_div_ck, 0x0,
833 OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, 824 OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
834 0x0, NULL); 825 0x0, NULL);
835 826
836DEFINE_CLK_GATE(efuse_ctrl_cust_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0,
837 OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
838 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
839
840DEFINE_CLK_GATE(emif1_fck, "ddrphy_ck", &ddrphy_ck, 0x0,
841 OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
842 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
843
844DEFINE_CLK_GATE(emif2_fck, "ddrphy_ck", &ddrphy_ck, 0x0,
845 OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
846 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
847
848DEFINE_CLK_DIVIDER(fdif_fck, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, 0x0, 827DEFINE_CLK_DIVIDER(fdif_fck, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, 0x0,
849 OMAP4430_CM_CAM_FDIF_CLKCTRL, OMAP4430_CLKSEL_FCLK_SHIFT, 828 OMAP4430_CM_CAM_FDIF_CLKCTRL, OMAP4430_CLKSEL_FCLK_SHIFT,
850 OMAP4430_CLKSEL_FCLK_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); 829 OMAP4430_CLKSEL_FCLK_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
851 830
852DEFINE_CLK_GATE(fpka_fck, "l4_div_ck", &l4_div_ck, 0x0,
853 OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
854 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
855
856DEFINE_CLK_GATE(gpio1_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, 831DEFINE_CLK_GATE(gpio1_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
857 OMAP4430_CM_WKUP_GPIO1_CLKCTRL, 832 OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
858 OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL); 833 OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL);
859 834
860DEFINE_CLK_GATE(gpio1_ick, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, 0x0,
861 OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
862 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
863
864DEFINE_CLK_GATE(gpio2_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, 835DEFINE_CLK_GATE(gpio2_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
865 OMAP4430_CM_L4PER_GPIO2_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 836 OMAP4430_CM_L4PER_GPIO2_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
866 0x0, NULL); 837 0x0, NULL);
867 838
868DEFINE_CLK_GATE(gpio2_ick, "l4_div_ck", &l4_div_ck, 0x0,
869 OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
870 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
871
872DEFINE_CLK_GATE(gpio3_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, 839DEFINE_CLK_GATE(gpio3_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
873 OMAP4430_CM_L4PER_GPIO3_CLKCTRL, 840 OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
874 OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL); 841 OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL);
875 842
876DEFINE_CLK_GATE(gpio3_ick, "l4_div_ck", &l4_div_ck, 0x0,
877 OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
878 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
879
880DEFINE_CLK_GATE(gpio4_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, 843DEFINE_CLK_GATE(gpio4_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
881 OMAP4430_CM_L4PER_GPIO4_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 844 OMAP4430_CM_L4PER_GPIO4_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
882 0x0, NULL); 845 0x0, NULL);
883 846
884DEFINE_CLK_GATE(gpio4_ick, "l4_div_ck", &l4_div_ck, 0x0,
885 OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
886 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
887
888DEFINE_CLK_GATE(gpio5_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, 847DEFINE_CLK_GATE(gpio5_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
889 OMAP4430_CM_L4PER_GPIO5_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 848 OMAP4430_CM_L4PER_GPIO5_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
890 0x0, NULL); 849 0x0, NULL);
891 850
892DEFINE_CLK_GATE(gpio5_ick, "l4_div_ck", &l4_div_ck, 0x0,
893 OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
894 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
895
896DEFINE_CLK_GATE(gpio6_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, 851DEFINE_CLK_GATE(gpio6_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
897 OMAP4430_CM_L4PER_GPIO6_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 852 OMAP4430_CM_L4PER_GPIO6_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
898 0x0, NULL); 853 0x0, NULL);
899 854
900DEFINE_CLK_GATE(gpio6_ick, "l4_div_ck", &l4_div_ck, 0x0,
901 OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
902 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
903
904DEFINE_CLK_GATE(gpmc_ick, "l3_div_ck", &l3_div_ck, 0x0,
905 OMAP4430_CM_L3_2_GPMC_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT,
906 0x0, NULL);
907
908static const struct clksel sgx_clk_mux_sel[] = { 855static const struct clksel sgx_clk_mux_sel[] = {
909 { .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates }, 856 { .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates },
910 { .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates }, 857 { .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates },
911 { .parent = NULL }, 858 { .parent = NULL },
912}; 859};
913 860
914static const char *gpu_fck_parents[] = { 861static const char *sgx_clk_mux_parents[] = {
915 "dpll_core_m7x2_ck", "dpll_per_m7x2_ck", 862 "dpll_core_m7x2_ck", "dpll_per_m7x2_ck",
916}; 863};
917 864
918/* Merged sgx_clk_mux into gpu */ 865DEFINE_CLK_OMAP_MUX(sgx_clk_mux, "l3_gfx_clkdm", sgx_clk_mux_sel,
919DEFINE_CLK_OMAP_MUX_GATE(gpu_fck, "l3_gfx_clkdm", sgx_clk_mux_sel, 866 OMAP4430_CM_GFX_GFX_CLKCTRL, OMAP4430_CLKSEL_SGX_FCLK_MASK,
920 OMAP4430_CM_GFX_GFX_CLKCTRL, 867 sgx_clk_mux_parents, func_dmic_abe_gfclk_ops);
921 OMAP4430_CLKSEL_SGX_FCLK_MASK,
922 OMAP4430_CM_GFX_GFX_CLKCTRL,
923 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
924 gpu_fck_parents, dmic_fck_ops);
925
926DEFINE_CLK_GATE(hdq1w_fck, "func_12m_fclk", &func_12m_fclk, 0x0,
927 OMAP4430_CM_L4PER_HDQ1W_CLKCTRL,
928 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
929 868
930DEFINE_CLK_DIVIDER(hsi_fck, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, 0x0, 869DEFINE_CLK_DIVIDER(hsi_fck, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, 0x0,
931 OMAP4430_CM_L3INIT_HSI_CLKCTRL, OMAP4430_CLKSEL_24_25_SHIFT, 870 OMAP4430_CM_L3INIT_HSI_CLKCTRL, OMAP4430_CLKSEL_24_25_SHIFT,
932 OMAP4430_CLKSEL_24_25_WIDTH, CLK_DIVIDER_POWER_OF_TWO, 871 OMAP4430_CLKSEL_24_25_WIDTH, CLK_DIVIDER_POWER_OF_TWO,
933 NULL); 872 NULL);
934 873
935DEFINE_CLK_GATE(i2c1_fck, "func_96m_fclk", &func_96m_fclk, 0x0,
936 OMAP4430_CM_L4PER_I2C1_CLKCTRL,
937 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
938
939DEFINE_CLK_GATE(i2c2_fck, "func_96m_fclk", &func_96m_fclk, 0x0,
940 OMAP4430_CM_L4PER_I2C2_CLKCTRL,
941 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
942
943DEFINE_CLK_GATE(i2c3_fck, "func_96m_fclk", &func_96m_fclk, 0x0,
944 OMAP4430_CM_L4PER_I2C3_CLKCTRL,
945 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
946
947DEFINE_CLK_GATE(i2c4_fck, "func_96m_fclk", &func_96m_fclk, 0x0,
948 OMAP4430_CM_L4PER_I2C4_CLKCTRL,
949 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
950
951DEFINE_CLK_GATE(ipu_fck, "ducati_clk_mux_ck", &ducati_clk_mux_ck, 0x0,
952 OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
953 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
954
955DEFINE_CLK_GATE(iss_ctrlclk, "func_96m_fclk", &func_96m_fclk, 0x0, 874DEFINE_CLK_GATE(iss_ctrlclk, "func_96m_fclk", &func_96m_fclk, 0x0,
956 OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT, 875 OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT,
957 0x0, NULL); 876 0x0, NULL);
958 877
959DEFINE_CLK_GATE(iss_fck, "ducati_clk_mux_ck", &ducati_clk_mux_ck, 0x0,
960 OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
961 0x0, NULL);
962
963DEFINE_CLK_GATE(iva_fck, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, 0x0,
964 OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
965 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
966
967DEFINE_CLK_GATE(kbd_fck, "sys_32k_ck", &sys_32k_ck, 0x0,
968 OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
969 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
970
971static struct clk l3_instr_ick;
972
973static const char *l3_instr_ick_parent_names[] = {
974 "l3_div_ck",
975};
976
977static const struct clk_ops l3_instr_ick_ops = {
978 .enable = &omap2_dflt_clk_enable,
979 .disable = &omap2_dflt_clk_disable,
980 .is_enabled = &omap2_dflt_clk_is_enabled,
981 .init = &omap2_init_clk_clkdm,
982};
983
984static struct clk_hw_omap l3_instr_ick_hw = {
985 .hw = {
986 .clk = &l3_instr_ick,
987 },
988 .enable_reg = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
989 .enable_bit = OMAP4430_MODULEMODE_HWCTRL_SHIFT,
990 .clkdm_name = "l3_instr_clkdm",
991};
992
993DEFINE_STRUCT_CLK(l3_instr_ick, l3_instr_ick_parent_names, l3_instr_ick_ops);
994
995static struct clk l3_main_3_ick;
996static struct clk_hw_omap l3_main_3_ick_hw = {
997 .hw = {
998 .clk = &l3_main_3_ick,
999 },
1000 .enable_reg = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
1001 .enable_bit = OMAP4430_MODULEMODE_HWCTRL_SHIFT,
1002 .clkdm_name = "l3_instr_clkdm",
1003};
1004
1005DEFINE_STRUCT_CLK(l3_main_3_ick, l3_instr_ick_parent_names, l3_instr_ick_ops);
1006
1007DEFINE_CLK_MUX(mcasp_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, 878DEFINE_CLK_MUX(mcasp_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
1008 OMAP4430_CM1_ABE_MCASP_CLKCTRL, 879 OMAP4430_CM1_ABE_MCASP_CLKCTRL,
1009 OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT, 880 OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT,
@@ -1016,17 +887,13 @@ static const struct clksel func_mcasp_abe_gfclk_sel[] = {
1016 { .parent = NULL }, 887 { .parent = NULL },
1017}; 888};
1018 889
1019static const char *mcasp_fck_parents[] = { 890static const char *func_mcasp_abe_gfclk_parents[] = {
1020 "mcasp_sync_mux_ck", "pad_clks_ck", "slimbus_clk", 891 "mcasp_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
1021}; 892};
1022 893
1023/* Merged func_mcasp_abe_gfclk into mcasp */ 894DEFINE_CLK_OMAP_MUX(func_mcasp_abe_gfclk, "abe_clkdm", func_mcasp_abe_gfclk_sel,
1024DEFINE_CLK_OMAP_MUX_GATE(mcasp_fck, "abe_clkdm", func_mcasp_abe_gfclk_sel, 895 OMAP4430_CM1_ABE_MCASP_CLKCTRL, OMAP4430_CLKSEL_SOURCE_MASK,
1025 OMAP4430_CM1_ABE_MCASP_CLKCTRL, 896 func_mcasp_abe_gfclk_parents, func_dmic_abe_gfclk_ops);
1026 OMAP4430_CLKSEL_SOURCE_MASK,
1027 OMAP4430_CM1_ABE_MCASP_CLKCTRL,
1028 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1029 mcasp_fck_parents, dmic_fck_ops);
1030 897
1031DEFINE_CLK_MUX(mcbsp1_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, 898DEFINE_CLK_MUX(mcbsp1_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
1032 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, 899 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
@@ -1040,17 +907,14 @@ static const struct clksel func_mcbsp1_gfclk_sel[] = {
1040 { .parent = NULL }, 907 { .parent = NULL },
1041}; 908};
1042 909
1043static const char *mcbsp1_fck_parents[] = { 910static const char *func_mcbsp1_gfclk_parents[] = {
1044 "mcbsp1_sync_mux_ck", "pad_clks_ck", "slimbus_clk", 911 "mcbsp1_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
1045}; 912};
1046 913
1047/* Merged func_mcbsp1_gfclk into mcbsp1 */ 914DEFINE_CLK_OMAP_MUX(func_mcbsp1_gfclk, "abe_clkdm", func_mcbsp1_gfclk_sel,
1048DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "abe_clkdm", func_mcbsp1_gfclk_sel, 915 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
1049 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, 916 OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp1_gfclk_parents,
1050 OMAP4430_CLKSEL_SOURCE_MASK, 917 func_dmic_abe_gfclk_ops);
1051 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
1052 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1053 mcbsp1_fck_parents, dmic_fck_ops);
1054 918
1055DEFINE_CLK_MUX(mcbsp2_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, 919DEFINE_CLK_MUX(mcbsp2_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
1056 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, 920 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
@@ -1064,17 +928,14 @@ static const struct clksel func_mcbsp2_gfclk_sel[] = {
1064 { .parent = NULL }, 928 { .parent = NULL },
1065}; 929};
1066 930
1067static const char *mcbsp2_fck_parents[] = { 931static const char *func_mcbsp2_gfclk_parents[] = {
1068 "mcbsp2_sync_mux_ck", "pad_clks_ck", "slimbus_clk", 932 "mcbsp2_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
1069}; 933};
1070 934
1071/* Merged func_mcbsp2_gfclk into mcbsp2 */ 935DEFINE_CLK_OMAP_MUX(func_mcbsp2_gfclk, "abe_clkdm", func_mcbsp2_gfclk_sel,
1072DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "abe_clkdm", func_mcbsp2_gfclk_sel, 936 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
1073 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, 937 OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp2_gfclk_parents,
1074 OMAP4430_CLKSEL_SOURCE_MASK, 938 func_dmic_abe_gfclk_ops);
1075 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
1076 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1077 mcbsp2_fck_parents, dmic_fck_ops);
1078 939
1079DEFINE_CLK_MUX(mcbsp3_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, 940DEFINE_CLK_MUX(mcbsp3_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
1080 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, 941 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
@@ -1088,17 +949,14 @@ static const struct clksel func_mcbsp3_gfclk_sel[] = {
1088 { .parent = NULL }, 949 { .parent = NULL },
1089}; 950};
1090 951
1091static const char *mcbsp3_fck_parents[] = { 952static const char *func_mcbsp3_gfclk_parents[] = {
1092 "mcbsp3_sync_mux_ck", "pad_clks_ck", "slimbus_clk", 953 "mcbsp3_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
1093}; 954};
1094 955
1095/* Merged func_mcbsp3_gfclk into mcbsp3 */ 956DEFINE_CLK_OMAP_MUX(func_mcbsp3_gfclk, "abe_clkdm", func_mcbsp3_gfclk_sel,
1096DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "abe_clkdm", func_mcbsp3_gfclk_sel, 957 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
1097 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, 958 OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp3_gfclk_parents,
1098 OMAP4430_CLKSEL_SOURCE_MASK, 959 func_dmic_abe_gfclk_ops);
1099 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
1100 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1101 mcbsp3_fck_parents, dmic_fck_ops);
1102 960
1103static const char *mcbsp4_sync_mux_ck_parents[] = { 961static const char *mcbsp4_sync_mux_ck_parents[] = {
1104 "func_96m_fclk", "per_abe_nc_fclk", 962 "func_96m_fclk", "per_abe_nc_fclk",
@@ -1115,37 +973,14 @@ static const struct clksel per_mcbsp4_gfclk_sel[] = {
1115 { .parent = NULL }, 973 { .parent = NULL },
1116}; 974};
1117 975
1118static const char *mcbsp4_fck_parents[] = { 976static const char *per_mcbsp4_gfclk_parents[] = {
1119 "mcbsp4_sync_mux_ck", "pad_clks_ck", 977 "mcbsp4_sync_mux_ck", "pad_clks_ck",
1120}; 978};
1121 979
1122/* Merged per_mcbsp4_gfclk into mcbsp4 */ 980DEFINE_CLK_OMAP_MUX(per_mcbsp4_gfclk, "l4_per_clkdm", per_mcbsp4_gfclk_sel,
1123DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "l4_per_clkdm", per_mcbsp4_gfclk_sel, 981 OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
1124 OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, 982 OMAP4430_CLKSEL_SOURCE_24_24_MASK, per_mcbsp4_gfclk_parents,
1125 OMAP4430_CLKSEL_SOURCE_24_24_MASK, 983 func_dmic_abe_gfclk_ops);
1126 OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
1127 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1128 mcbsp4_fck_parents, dmic_fck_ops);
1129
1130DEFINE_CLK_GATE(mcpdm_fck, "pad_clks_ck", &pad_clks_ck, 0x0,
1131 OMAP4430_CM1_ABE_PDM_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
1132 0x0, NULL);
1133
1134DEFINE_CLK_GATE(mcspi1_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
1135 OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
1136 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1137
1138DEFINE_CLK_GATE(mcspi2_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
1139 OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
1140 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1141
1142DEFINE_CLK_GATE(mcspi3_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
1143 OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
1144 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1145
1146DEFINE_CLK_GATE(mcspi4_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
1147 OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
1148 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1149 984
1150static const struct clksel hsmmc1_fclk_sel[] = { 985static const struct clksel hsmmc1_fclk_sel[] = {
1151 { .parent = &func_64m_fclk, .rates = div_1_0_rates }, 986 { .parent = &func_64m_fclk, .rates = div_1_0_rates },
@@ -1153,69 +988,22 @@ static const struct clksel hsmmc1_fclk_sel[] = {
1153 { .parent = NULL }, 988 { .parent = NULL },
1154}; 989};
1155 990
1156static const char *mmc1_fck_parents[] = { 991static const char *hsmmc1_fclk_parents[] = {
1157 "func_64m_fclk", "func_96m_fclk", 992 "func_64m_fclk", "func_96m_fclk",
1158}; 993};
1159 994
1160/* Merged hsmmc1_fclk into mmc1 */ 995DEFINE_CLK_OMAP_MUX(hsmmc1_fclk, "l3_init_clkdm", hsmmc1_fclk_sel,
1161DEFINE_CLK_OMAP_MUX_GATE(mmc1_fck, "l3_init_clkdm", hsmmc1_fclk_sel, 996 OMAP4430_CM_L3INIT_MMC1_CLKCTRL, OMAP4430_CLKSEL_MASK,
1162 OMAP4430_CM_L3INIT_MMC1_CLKCTRL, OMAP4430_CLKSEL_MASK, 997 hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops);
1163 OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
1164 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1165 mmc1_fck_parents, dmic_fck_ops);
1166
1167/* Merged hsmmc2_fclk into mmc2 */
1168DEFINE_CLK_OMAP_MUX_GATE(mmc2_fck, "l3_init_clkdm", hsmmc1_fclk_sel,
1169 OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK,
1170 OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
1171 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1172 mmc1_fck_parents, dmic_fck_ops);
1173
1174DEFINE_CLK_GATE(mmc3_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
1175 OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
1176 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1177
1178DEFINE_CLK_GATE(mmc4_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
1179 OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
1180 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1181
1182DEFINE_CLK_GATE(mmc5_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
1183 OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
1184 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1185
1186DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0,
1187 OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
1188 OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL);
1189
1190DEFINE_CLK_GATE(ocp2scp_usb_phy_ick, "l4_div_ck", &l4_div_ck, 0x0,
1191 OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
1192 OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
1193
1194static struct clk ocp_wp_noc_ick;
1195
1196static struct clk_hw_omap ocp_wp_noc_ick_hw = {
1197 .hw = {
1198 .clk = &ocp_wp_noc_ick,
1199 },
1200 .enable_reg = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
1201 .enable_bit = OMAP4430_MODULEMODE_HWCTRL_SHIFT,
1202 .clkdm_name = "l3_instr_clkdm",
1203};
1204
1205DEFINE_STRUCT_CLK(ocp_wp_noc_ick, l3_instr_ick_parent_names, l3_instr_ick_ops);
1206 998
1207DEFINE_CLK_GATE(rng_ick, "l4_div_ck", &l4_div_ck, 0x0, 999DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel,
1208 OMAP4430_CM_L4SEC_RNG_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, 1000 OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK,
1209 0x0, NULL); 1001 hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops);
1210 1002
1211DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0, 1003DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0,
1212 OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL, 1004 OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
1213 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); 1005 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1214 1006
1215DEFINE_CLK_GATE(sl2if_ick, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, 0x0,
1216 OMAP4430_CM_IVAHD_SL2_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT,
1217 0x0, NULL);
1218
1219DEFINE_CLK_GATE(slimbus1_fclk_1, "func_24m_clk", &func_24m_clk, 0x0, 1007DEFINE_CLK_GATE(slimbus1_fclk_1, "func_24m_clk", &func_24m_clk, 0x0,
1220 OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL, 1008 OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
1221 OMAP4430_OPTFCLKEN_FCLK1_SHIFT, 0x0, NULL); 1009 OMAP4430_OPTFCLKEN_FCLK1_SHIFT, 0x0, NULL);
@@ -1232,10 +1020,6 @@ DEFINE_CLK_GATE(slimbus1_slimbus_clk, "slimbus_clk", &slimbus_clk, 0x0,
1232 OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL, 1020 OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
1233 OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT, 0x0, NULL); 1021 OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT, 0x0, NULL);
1234 1022
1235DEFINE_CLK_GATE(slimbus1_fck, "ocp_abe_iclk", &ocp_abe_iclk, 0x0,
1236 OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
1237 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1238
1239DEFINE_CLK_GATE(slimbus2_fclk_1, "per_abe_24m_fclk", &per_abe_24m_fclk, 0x0, 1023DEFINE_CLK_GATE(slimbus2_fclk_1, "per_abe_24m_fclk", &per_abe_24m_fclk, 0x0,
1240 OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL, 1024 OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
1241 OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT, 0x0, NULL); 1025 OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT, 0x0, NULL);
@@ -1249,10 +1033,6 @@ DEFINE_CLK_GATE(slimbus2_slimbus_clk, "pad_slimbus_core_clks_ck",
1249 OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL, 1033 OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
1250 OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT, 0x0, NULL); 1034 OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT, 0x0, NULL);
1251 1035
1252DEFINE_CLK_GATE(slimbus2_fck, "l4_div_ck", &l4_div_ck, 0x0,
1253 OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
1254 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1255
1256DEFINE_CLK_GATE(smartreflex_core_fck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, 1036DEFINE_CLK_GATE(smartreflex_core_fck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck,
1257 0x0, OMAP4430_CM_ALWON_SR_CORE_CLKCTRL, 1037 0x0, OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
1258 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); 1038 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
@@ -1271,52 +1051,35 @@ static const struct clksel dmt1_clk_mux_sel[] = {
1271 { .parent = NULL }, 1051 { .parent = NULL },
1272}; 1052};
1273 1053
1274/* Merged dmt1_clk_mux into timer1 */ 1054DEFINE_CLK_OMAP_MUX(dmt1_clk_mux, "l4_wkup_clkdm", dmt1_clk_mux_sel,
1275DEFINE_CLK_OMAP_MUX_GATE(timer1_fck, "l4_wkup_clkdm", dmt1_clk_mux_sel, 1055 OMAP4430_CM_WKUP_TIMER1_CLKCTRL, OMAP4430_CLKSEL_MASK,
1276 OMAP4430_CM_WKUP_TIMER1_CLKCTRL, OMAP4430_CLKSEL_MASK, 1056 abe_dpll_bypass_clk_mux_ck_parents,
1277 OMAP4430_CM_WKUP_TIMER1_CLKCTRL, 1057 func_dmic_abe_gfclk_ops);
1278 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, 1058
1279 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); 1059DEFINE_CLK_OMAP_MUX(cm2_dm10_mux, "l4_per_clkdm", dmt1_clk_mux_sel,
1280 1060 OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, OMAP4430_CLKSEL_MASK,
1281/* Merged cm2_dm10_mux into timer10 */ 1061 abe_dpll_bypass_clk_mux_ck_parents,
1282DEFINE_CLK_OMAP_MUX_GATE(timer10_fck, "l4_per_clkdm", dmt1_clk_mux_sel, 1062 func_dmic_abe_gfclk_ops);
1283 OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, 1063
1284 OMAP4430_CLKSEL_MASK, 1064DEFINE_CLK_OMAP_MUX(cm2_dm11_mux, "l4_per_clkdm", dmt1_clk_mux_sel,
1285 OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, 1065 OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, OMAP4430_CLKSEL_MASK,
1286 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, 1066 abe_dpll_bypass_clk_mux_ck_parents,
1287 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); 1067 func_dmic_abe_gfclk_ops);
1288 1068
1289/* Merged cm2_dm11_mux into timer11 */ 1069DEFINE_CLK_OMAP_MUX(cm2_dm2_mux, "l4_per_clkdm", dmt1_clk_mux_sel,
1290DEFINE_CLK_OMAP_MUX_GATE(timer11_fck, "l4_per_clkdm", dmt1_clk_mux_sel, 1070 OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, OMAP4430_CLKSEL_MASK,
1291 OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, 1071 abe_dpll_bypass_clk_mux_ck_parents,
1292 OMAP4430_CLKSEL_MASK, 1072 func_dmic_abe_gfclk_ops);
1293 OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, 1073
1294 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, 1074DEFINE_CLK_OMAP_MUX(cm2_dm3_mux, "l4_per_clkdm", dmt1_clk_mux_sel,
1295 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); 1075 OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, OMAP4430_CLKSEL_MASK,
1296 1076 abe_dpll_bypass_clk_mux_ck_parents,
1297/* Merged cm2_dm2_mux into timer2 */ 1077 func_dmic_abe_gfclk_ops);
1298DEFINE_CLK_OMAP_MUX_GATE(timer2_fck, "l4_per_clkdm", dmt1_clk_mux_sel, 1078
1299 OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, 1079DEFINE_CLK_OMAP_MUX(cm2_dm4_mux, "l4_per_clkdm", dmt1_clk_mux_sel,
1300 OMAP4430_CLKSEL_MASK, 1080 OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, OMAP4430_CLKSEL_MASK,
1301 OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, 1081 abe_dpll_bypass_clk_mux_ck_parents,
1302 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, 1082 func_dmic_abe_gfclk_ops);
1303 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
1304
1305/* Merged cm2_dm3_mux into timer3 */
1306DEFINE_CLK_OMAP_MUX_GATE(timer3_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
1307 OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
1308 OMAP4430_CLKSEL_MASK,
1309 OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
1310 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1311 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
1312
1313/* Merged cm2_dm4_mux into timer4 */
1314DEFINE_CLK_OMAP_MUX_GATE(timer4_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
1315 OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
1316 OMAP4430_CLKSEL_MASK,
1317 OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
1318 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1319 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
1320 1083
1321static const struct clksel timer5_sync_mux_sel[] = { 1084static const struct clksel timer5_sync_mux_sel[] = {
1322 { .parent = &syc_clk_div_ck, .rates = div_1_0_rates }, 1085 { .parent = &syc_clk_div_ck, .rates = div_1_0_rates },
@@ -1324,61 +1087,30 @@ static const struct clksel timer5_sync_mux_sel[] = {
1324 { .parent = NULL }, 1087 { .parent = NULL },
1325}; 1088};
1326 1089
1327static const char *timer5_fck_parents[] = { 1090static const char *timer5_sync_mux_parents[] = {
1328 "syc_clk_div_ck", "sys_32k_ck", 1091 "syc_clk_div_ck", "sys_32k_ck",
1329}; 1092};
1330 1093
1331/* Merged timer5_sync_mux into timer5 */ 1094DEFINE_CLK_OMAP_MUX(timer5_sync_mux, "abe_clkdm", timer5_sync_mux_sel,
1332DEFINE_CLK_OMAP_MUX_GATE(timer5_fck, "abe_clkdm", timer5_sync_mux_sel, 1095 OMAP4430_CM1_ABE_TIMER5_CLKCTRL, OMAP4430_CLKSEL_MASK,
1333 OMAP4430_CM1_ABE_TIMER5_CLKCTRL, OMAP4430_CLKSEL_MASK, 1096 timer5_sync_mux_parents, func_dmic_abe_gfclk_ops);
1334 OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
1335 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1336 timer5_fck_parents, dmic_fck_ops);
1337
1338/* Merged timer6_sync_mux into timer6 */
1339DEFINE_CLK_OMAP_MUX_GATE(timer6_fck, "abe_clkdm", timer5_sync_mux_sel,
1340 OMAP4430_CM1_ABE_TIMER6_CLKCTRL, OMAP4430_CLKSEL_MASK,
1341 OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
1342 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1343 timer5_fck_parents, dmic_fck_ops);
1344
1345/* Merged timer7_sync_mux into timer7 */
1346DEFINE_CLK_OMAP_MUX_GATE(timer7_fck, "abe_clkdm", timer5_sync_mux_sel,
1347 OMAP4430_CM1_ABE_TIMER7_CLKCTRL, OMAP4430_CLKSEL_MASK,
1348 OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
1349 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1350 timer5_fck_parents, dmic_fck_ops);
1351
1352/* Merged timer8_sync_mux into timer8 */
1353DEFINE_CLK_OMAP_MUX_GATE(timer8_fck, "abe_clkdm", timer5_sync_mux_sel,
1354 OMAP4430_CM1_ABE_TIMER8_CLKCTRL, OMAP4430_CLKSEL_MASK,
1355 OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
1356 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1357 timer5_fck_parents, dmic_fck_ops);
1358
1359/* Merged cm2_dm9_mux into timer9 */
1360DEFINE_CLK_OMAP_MUX_GATE(timer9_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
1361 OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
1362 OMAP4430_CLKSEL_MASK,
1363 OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
1364 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
1365 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
1366
1367DEFINE_CLK_GATE(uart1_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
1368 OMAP4430_CM_L4PER_UART1_CLKCTRL,
1369 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
1370 1097
1371DEFINE_CLK_GATE(uart2_fck, "func_48m_fclk", &func_48m_fclk, 0x0, 1098DEFINE_CLK_OMAP_MUX(timer6_sync_mux, "abe_clkdm", timer5_sync_mux_sel,
1372 OMAP4430_CM_L4PER_UART2_CLKCTRL, 1099 OMAP4430_CM1_ABE_TIMER6_CLKCTRL, OMAP4430_CLKSEL_MASK,
1373 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); 1100 timer5_sync_mux_parents, func_dmic_abe_gfclk_ops);
1374 1101
1375DEFINE_CLK_GATE(uart3_fck, "func_48m_fclk", &func_48m_fclk, 0x0, 1102DEFINE_CLK_OMAP_MUX(timer7_sync_mux, "abe_clkdm", timer5_sync_mux_sel,
1376 OMAP4430_CM_L4PER_UART3_CLKCTRL, 1103 OMAP4430_CM1_ABE_TIMER7_CLKCTRL, OMAP4430_CLKSEL_MASK,
1377 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); 1104 timer5_sync_mux_parents, func_dmic_abe_gfclk_ops);
1378 1105
1379DEFINE_CLK_GATE(uart4_fck, "func_48m_fclk", &func_48m_fclk, 0x0, 1106DEFINE_CLK_OMAP_MUX(timer8_sync_mux, "abe_clkdm", timer5_sync_mux_sel,
1380 OMAP4430_CM_L4PER_UART4_CLKCTRL, 1107 OMAP4430_CM1_ABE_TIMER8_CLKCTRL, OMAP4430_CLKSEL_MASK,
1381 OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); 1108 timer5_sync_mux_parents, func_dmic_abe_gfclk_ops);
1109
1110DEFINE_CLK_OMAP_MUX(cm2_dm9_mux, "l4_per_clkdm", dmt1_clk_mux_sel,
1111 OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, OMAP4430_CLKSEL_MASK,
1112 abe_dpll_bypass_clk_mux_ck_parents,
1113 func_dmic_abe_gfclk_ops);
1382 1114
1383static struct clk usb_host_fs_fck; 1115static struct clk usb_host_fs_fck;
1384 1116
@@ -1512,18 +1244,6 @@ DEFINE_CLK_GATE(usim_fclk, "usim_ck", &usim_ck, 0x0,
1512 OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_OPTFCLKEN_FCLK_SHIFT, 1244 OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_OPTFCLKEN_FCLK_SHIFT,
1513 0x0, NULL); 1245 0x0, NULL);
1514 1246
1515DEFINE_CLK_GATE(usim_fck, "sys_32k_ck", &sys_32k_ck, 0x0,
1516 OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT,
1517 0x0, NULL);
1518
1519DEFINE_CLK_GATE(wd_timer2_fck, "sys_32k_ck", &sys_32k_ck, 0x0,
1520 OMAP4430_CM_WKUP_WDT2_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
1521 0x0, NULL);
1522
1523DEFINE_CLK_GATE(wd_timer3_fck, "sys_32k_ck", &sys_32k_ck, 0x0,
1524 OMAP4430_CM1_ABE_WDT3_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
1525 0x0, NULL);
1526
1527/* Remaining optional clocks */ 1247/* Remaining optional clocks */
1528static const char *pmd_stm_clock_mux_ck_parents[] = { 1248static const char *pmd_stm_clock_mux_ck_parents[] = {
1529 "sys_clkin_ck", "dpll_core_m6x2_ck", "tie_low_clock_ck", 1249 "sys_clkin_ck", "dpll_core_m6x2_ck", "tie_low_clock_ck",
@@ -1774,106 +1494,61 @@ static struct omap_clk omap44xx_clks[] = {
1774 CLK(NULL, "syc_clk_div_ck", &syc_clk_div_ck, CK_443X), 1494 CLK(NULL, "syc_clk_div_ck", &syc_clk_div_ck, CK_443X),
1775 CLK(NULL, "aes1_fck", &aes1_fck, CK_443X), 1495 CLK(NULL, "aes1_fck", &aes1_fck, CK_443X),
1776 CLK(NULL, "aes2_fck", &aes2_fck, CK_443X), 1496 CLK(NULL, "aes2_fck", &aes2_fck, CK_443X),
1777 CLK(NULL, "aess_fck", &aess_fck, CK_443X),
1778 CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X), 1497 CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X),
1779 CLK(NULL, "div_ts_ck", &div_ts_ck, CK_446X), 1498 CLK(NULL, "div_ts_ck", &div_ts_ck, CK_446X),
1780 CLK(NULL, "bandgap_ts_fclk", &bandgap_ts_fclk, CK_446X), 1499 CLK(NULL, "bandgap_ts_fclk", &bandgap_ts_fclk, CK_446X),
1781 CLK(NULL, "des3des_fck", &des3des_fck, CK_443X),
1782 CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X), 1500 CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X),
1783 CLK(NULL, "dmic_fck", &dmic_fck, CK_443X), 1501 CLK(NULL, "func_dmic_abe_gfclk", &func_dmic_abe_gfclk, CK_443X),
1784 CLK(NULL, "dsp_fck", &dsp_fck, CK_443X),
1785 CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X), 1502 CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X),
1786 CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X), 1503 CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X),
1787 CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X), 1504 CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X),
1788 CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X), 1505 CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X),
1789 CLK(NULL, "dss_fck", &dss_fck, CK_443X), 1506 CLK(NULL, "dss_fck", &dss_fck, CK_443X),
1790 CLK("omapdss_dss", "ick", &dss_fck, CK_443X), 1507 CLK("omapdss_dss", "ick", &dss_fck, CK_443X),
1791 CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
1792 CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
1793 CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
1794 CLK(NULL, "fdif_fck", &fdif_fck, CK_443X), 1508 CLK(NULL, "fdif_fck", &fdif_fck, CK_443X),
1795 CLK(NULL, "fpka_fck", &fpka_fck, CK_443X),
1796 CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_443X), 1509 CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_443X),
1797 CLK(NULL, "gpio1_ick", &gpio1_ick, CK_443X),
1798 CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_443X), 1510 CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_443X),
1799 CLK(NULL, "gpio2_ick", &gpio2_ick, CK_443X),
1800 CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_443X), 1511 CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_443X),
1801 CLK(NULL, "gpio3_ick", &gpio3_ick, CK_443X),
1802 CLK(NULL, "gpio4_dbclk", &gpio4_dbclk, CK_443X), 1512 CLK(NULL, "gpio4_dbclk", &gpio4_dbclk, CK_443X),
1803 CLK(NULL, "gpio4_ick", &gpio4_ick, CK_443X),
1804 CLK(NULL, "gpio5_dbclk", &gpio5_dbclk, CK_443X), 1513 CLK(NULL, "gpio5_dbclk", &gpio5_dbclk, CK_443X),
1805 CLK(NULL, "gpio5_ick", &gpio5_ick, CK_443X),
1806 CLK(NULL, "gpio6_dbclk", &gpio6_dbclk, CK_443X), 1514 CLK(NULL, "gpio6_dbclk", &gpio6_dbclk, CK_443X),
1807 CLK(NULL, "gpio6_ick", &gpio6_ick, CK_443X), 1515 CLK(NULL, "sgx_clk_mux", &sgx_clk_mux, CK_443X),
1808 CLK(NULL, "gpmc_ick", &gpmc_ick, CK_443X),
1809 CLK(NULL, "gpu_fck", &gpu_fck, CK_443X),
1810 CLK(NULL, "hdq1w_fck", &hdq1w_fck, CK_443X),
1811 CLK(NULL, "hsi_fck", &hsi_fck, CK_443X), 1516 CLK(NULL, "hsi_fck", &hsi_fck, CK_443X),
1812 CLK(NULL, "i2c1_fck", &i2c1_fck, CK_443X),
1813 CLK(NULL, "i2c2_fck", &i2c2_fck, CK_443X),
1814 CLK(NULL, "i2c3_fck", &i2c3_fck, CK_443X),
1815 CLK(NULL, "i2c4_fck", &i2c4_fck, CK_443X),
1816 CLK(NULL, "ipu_fck", &ipu_fck, CK_443X),
1817 CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X), 1517 CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X),
1818 CLK(NULL, "iss_fck", &iss_fck, CK_443X),
1819 CLK(NULL, "iva_fck", &iva_fck, CK_443X),
1820 CLK(NULL, "kbd_fck", &kbd_fck, CK_443X),
1821 CLK(NULL, "l3_instr_ick", &l3_instr_ick, CK_443X),
1822 CLK(NULL, "l3_main_3_ick", &l3_main_3_ick, CK_443X),
1823 CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_443X), 1518 CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_443X),
1824 CLK(NULL, "mcasp_fck", &mcasp_fck, CK_443X), 1519 CLK(NULL, "func_mcasp_abe_gfclk", &func_mcasp_abe_gfclk, CK_443X),
1825 CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_443X), 1520 CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_443X),
1826 CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_443X), 1521 CLK(NULL, "func_mcbsp1_gfclk", &func_mcbsp1_gfclk, CK_443X),
1827 CLK(NULL, "mcbsp2_sync_mux_ck", &mcbsp2_sync_mux_ck, CK_443X), 1522 CLK(NULL, "mcbsp2_sync_mux_ck", &mcbsp2_sync_mux_ck, CK_443X),
1828 CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_443X), 1523 CLK(NULL, "func_mcbsp2_gfclk", &func_mcbsp2_gfclk, CK_443X),
1829 CLK(NULL, "mcbsp3_sync_mux_ck", &mcbsp3_sync_mux_ck, CK_443X), 1524 CLK(NULL, "mcbsp3_sync_mux_ck", &mcbsp3_sync_mux_ck, CK_443X),
1830 CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_443X), 1525 CLK(NULL, "func_mcbsp3_gfclk", &func_mcbsp3_gfclk, CK_443X),
1831 CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_443X), 1526 CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_443X),
1832 CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_443X), 1527 CLK(NULL, "per_mcbsp4_gfclk", &per_mcbsp4_gfclk, CK_443X),
1833 CLK(NULL, "mcpdm_fck", &mcpdm_fck, CK_443X), 1528 CLK(NULL, "hsmmc1_fclk", &hsmmc1_fclk, CK_443X),
1834 CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_443X), 1529 CLK(NULL, "hsmmc2_fclk", &hsmmc2_fclk, CK_443X),
1835 CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_443X),
1836 CLK(NULL, "mcspi3_fck", &mcspi3_fck, CK_443X),
1837 CLK(NULL, "mcspi4_fck", &mcspi4_fck, CK_443X),
1838 CLK(NULL, "mmc1_fck", &mmc1_fck, CK_443X),
1839 CLK(NULL, "mmc2_fck", &mmc2_fck, CK_443X),
1840 CLK(NULL, "mmc3_fck", &mmc3_fck, CK_443X),
1841 CLK(NULL, "mmc4_fck", &mmc4_fck, CK_443X),
1842 CLK(NULL, "mmc5_fck", &mmc5_fck, CK_443X),
1843 CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X),
1844 CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_443X),
1845 CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_443X),
1846 CLK(NULL, "rng_ick", &rng_ick, CK_443X),
1847 CLK("omap_rng", "ick", &rng_ick, CK_443X),
1848 CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X), 1530 CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X),
1849 CLK(NULL, "sl2if_ick", &sl2if_ick, CK_443X),
1850 CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X), 1531 CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X),
1851 CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X), 1532 CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X),
1852 CLK(NULL, "slimbus1_fclk_2", &slimbus1_fclk_2, CK_443X), 1533 CLK(NULL, "slimbus1_fclk_2", &slimbus1_fclk_2, CK_443X),
1853 CLK(NULL, "slimbus1_slimbus_clk", &slimbus1_slimbus_clk, CK_443X), 1534 CLK(NULL, "slimbus1_slimbus_clk", &slimbus1_slimbus_clk, CK_443X),
1854 CLK(NULL, "slimbus1_fck", &slimbus1_fck, CK_443X),
1855 CLK(NULL, "slimbus2_fclk_1", &slimbus2_fclk_1, CK_443X), 1535 CLK(NULL, "slimbus2_fclk_1", &slimbus2_fclk_1, CK_443X),
1856 CLK(NULL, "slimbus2_fclk_0", &slimbus2_fclk_0, CK_443X), 1536 CLK(NULL, "slimbus2_fclk_0", &slimbus2_fclk_0, CK_443X),
1857 CLK(NULL, "slimbus2_slimbus_clk", &slimbus2_slimbus_clk, CK_443X), 1537 CLK(NULL, "slimbus2_slimbus_clk", &slimbus2_slimbus_clk, CK_443X),
1858 CLK(NULL, "slimbus2_fck", &slimbus2_fck, CK_443X),
1859 CLK(NULL, "smartreflex_core_fck", &smartreflex_core_fck, CK_443X), 1538 CLK(NULL, "smartreflex_core_fck", &smartreflex_core_fck, CK_443X),
1860 CLK(NULL, "smartreflex_iva_fck", &smartreflex_iva_fck, CK_443X), 1539 CLK(NULL, "smartreflex_iva_fck", &smartreflex_iva_fck, CK_443X),
1861 CLK(NULL, "smartreflex_mpu_fck", &smartreflex_mpu_fck, CK_443X), 1540 CLK(NULL, "smartreflex_mpu_fck", &smartreflex_mpu_fck, CK_443X),
1862 CLK(NULL, "timer1_fck", &timer1_fck, CK_443X), 1541 CLK(NULL, "dmt1_clk_mux", &dmt1_clk_mux, CK_443X),
1863 CLK(NULL, "timer10_fck", &timer10_fck, CK_443X), 1542 CLK(NULL, "cm2_dm10_mux", &cm2_dm10_mux, CK_443X),
1864 CLK(NULL, "timer11_fck", &timer11_fck, CK_443X), 1543 CLK(NULL, "cm2_dm11_mux", &cm2_dm11_mux, CK_443X),
1865 CLK(NULL, "timer2_fck", &timer2_fck, CK_443X), 1544 CLK(NULL, "cm2_dm2_mux", &cm2_dm2_mux, CK_443X),
1866 CLK(NULL, "timer3_fck", &timer3_fck, CK_443X), 1545 CLK(NULL, "cm2_dm3_mux", &cm2_dm3_mux, CK_443X),
1867 CLK(NULL, "timer4_fck", &timer4_fck, CK_443X), 1546 CLK(NULL, "cm2_dm4_mux", &cm2_dm4_mux, CK_443X),
1868 CLK(NULL, "timer5_fck", &timer5_fck, CK_443X), 1547 CLK(NULL, "timer5_sync_mux", &timer5_sync_mux, CK_443X),
1869 CLK(NULL, "timer6_fck", &timer6_fck, CK_443X), 1548 CLK(NULL, "timer6_sync_mux", &timer6_sync_mux, CK_443X),
1870 CLK(NULL, "timer7_fck", &timer7_fck, CK_443X), 1549 CLK(NULL, "timer7_sync_mux", &timer7_sync_mux, CK_443X),
1871 CLK(NULL, "timer8_fck", &timer8_fck, CK_443X), 1550 CLK(NULL, "timer8_sync_mux", &timer8_sync_mux, CK_443X),
1872 CLK(NULL, "timer9_fck", &timer9_fck, CK_443X), 1551 CLK(NULL, "cm2_dm9_mux", &cm2_dm9_mux, CK_443X),
1873 CLK(NULL, "uart1_fck", &uart1_fck, CK_443X),
1874 CLK(NULL, "uart2_fck", &uart2_fck, CK_443X),
1875 CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
1876 CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
1877 CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X), 1552 CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X),
1878 CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X), 1553 CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X),
1879 CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), 1554 CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
@@ -1901,9 +1576,6 @@ static struct omap_clk omap44xx_clks[] = {
1901 CLK("usbhs_tll", "usbtll_ick", &usb_tll_hs_ick, CK_443X), 1576 CLK("usbhs_tll", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
1902 CLK(NULL, "usim_ck", &usim_ck, CK_443X), 1577 CLK(NULL, "usim_ck", &usim_ck, CK_443X),
1903 CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), 1578 CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
1904 CLK(NULL, "usim_fck", &usim_fck, CK_443X),
1905 CLK(NULL, "wd_timer2_fck", &wd_timer2_fck, CK_443X),
1906 CLK(NULL, "wd_timer3_fck", &wd_timer3_fck, CK_443X),
1907 CLK(NULL, "pmd_stm_clock_mux_ck", &pmd_stm_clock_mux_ck, CK_443X), 1579 CLK(NULL, "pmd_stm_clock_mux_ck", &pmd_stm_clock_mux_ck, CK_443X),
1908 CLK(NULL, "pmd_trace_clk_mux_ck", &pmd_trace_clk_mux_ck, CK_443X), 1580 CLK(NULL, "pmd_trace_clk_mux_ck", &pmd_trace_clk_mux_ck, CK_443X),
1909 CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X), 1581 CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X),
@@ -1980,15 +1652,6 @@ static struct omap_clk omap44xx_clks[] = {
1980 CLK(NULL, "cpufreq_ck", &dpll_mpu_ck, CK_443X), 1652 CLK(NULL, "cpufreq_ck", &dpll_mpu_ck, CK_443X),
1981}; 1653};
1982 1654
1983static const char *enable_init_clks[] = {
1984 "emif1_fck",
1985 "emif2_fck",
1986 "gpmc_ick",
1987 "l3_instr_ick",
1988 "l3_main_3_ick",
1989 "ocp_wp_noc_ick",
1990};
1991
1992int __init omap4xxx_clk_init(void) 1655int __init omap4xxx_clk_init(void)
1993{ 1656{
1994 u32 cpu_clkflg; 1657 u32 cpu_clkflg;
@@ -2019,9 +1682,6 @@ int __init omap4xxx_clk_init(void)
2019 1682
2020 omap2_clk_disable_autoidle_all(); 1683 omap2_clk_disable_autoidle_all();
2021 1684
2022 omap2_clk_enable_init_clocks(enable_init_clks,
2023 ARRAY_SIZE(enable_init_clks));
2024
2025 /* 1685 /*
2026 * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power 1686 * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power
2027 * state when turning the ABE clock domain. Workaround this by 1687 * state when turning the ABE clock domain. Workaround this by
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 7faf82d4e85c..2da3b5ec010c 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -92,8 +92,6 @@ static int _clkdm_register(struct clockdomain *clkdm)
92 92
93 pwrdm_add_clkdm(pwrdm, clkdm); 93 pwrdm_add_clkdm(pwrdm, clkdm);
94 94
95 spin_lock_init(&clkdm->lock);
96
97 pr_debug("clockdomain: registered %s\n", clkdm->name); 95 pr_debug("clockdomain: registered %s\n", clkdm->name);
98 96
99 return 0; 97 return 0;
@@ -122,7 +120,7 @@ static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,
122 return cd; 120 return cd;
123} 121}
124 122
125/* 123/**
126 * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store 124 * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store
127 * @autodep: struct clkdm_autodep * to resolve 125 * @autodep: struct clkdm_autodep * to resolve
128 * 126 *
@@ -154,88 +152,206 @@ static void _autodep_lookup(struct clkdm_autodep *autodep)
154 autodep->clkdm.ptr = clkdm; 152 autodep->clkdm.ptr = clkdm;
155} 153}
156 154
157/* 155/**
158 * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable 156 * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms
159 * @clkdm: struct clockdomain * 157 * @clkdm: clockdomain that we are resolving dependencies for
158 * @clkdm_deps: ptr to array of struct clkdm_deps to resolve
160 * 159 *
161 * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' 160 * Iterates through @clkdm_deps, looking up the struct clockdomain named by
162 * in hardware-supervised mode. Meant to be called from clock framework 161 * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep.
163 * when a clock inside clockdomain 'clkdm' is enabled. No return value. 162 * No return value.
163 */
164static void _resolve_clkdm_deps(struct clockdomain *clkdm,
165 struct clkdm_dep *clkdm_deps)
166{
167 struct clkdm_dep *cd;
168
169 for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) {
170 if (cd->clkdm)
171 continue;
172 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
173
174 WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen",
175 clkdm->name, cd->clkdm_name);
176 }
177}
178
179/**
180 * _clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 (lockless)
181 * @clkdm1: wake this struct clockdomain * up (dependent)
182 * @clkdm2: when this struct clockdomain * wakes up (source)
164 * 183 *
165 * XXX autodeps are deprecated and should be removed at the earliest 184 * When the clockdomain represented by @clkdm2 wakes up, wake up
166 * opportunity 185 * @clkdm1. Implemented in hardware on the OMAP, this feature is
186 * designed to reduce wakeup latency of the dependent clockdomain @clkdm1.
187 * Returns -EINVAL if presented with invalid clockdomain pointers,
188 * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon
189 * success.
167 */ 190 */
168void _clkdm_add_autodeps(struct clockdomain *clkdm) 191static int _clkdm_add_wkdep(struct clockdomain *clkdm1,
192 struct clockdomain *clkdm2)
169{ 193{
170 struct clkdm_autodep *autodep; 194 struct clkdm_dep *cd;
195 int ret = 0;
171 196
172 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) 197 if (!clkdm1 || !clkdm2)
173 return; 198 return -EINVAL;
174 199
175 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { 200 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
176 if (IS_ERR(autodep->clkdm.ptr)) 201 if (IS_ERR(cd))
177 continue; 202 ret = PTR_ERR(cd);
178 203
179 pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n", 204 if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep)
180 clkdm->name, autodep->clkdm.ptr->name); 205 ret = -EINVAL;
206
207 if (ret) {
208 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n",
209 clkdm1->name, clkdm2->name);
210 return ret;
211 }
212
213 cd->wkdep_usecount++;
214 if (cd->wkdep_usecount == 1) {
215 pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n",
216 clkdm1->name, clkdm2->name);
181 217
182 clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr); 218 ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
183 clkdm_add_wkdep(clkdm, autodep->clkdm.ptr);
184 } 219 }
220
221 return ret;
185} 222}
186 223
187/* 224/**
188 * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm 225 * _clkdm_del_wkdep - remove a wakeup dep from clkdm2 to clkdm1 (lockless)
189 * @clkdm: struct clockdomain * 226 * @clkdm1: wake this struct clockdomain * up (dependent)
227 * @clkdm2: when this struct clockdomain * wakes up (source)
190 * 228 *
191 * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' 229 * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2
192 * in hardware-supervised mode. Meant to be called from clock framework 230 * wakes up. Returns -EINVAL if presented with invalid clockdomain
193 * when a clock inside clockdomain 'clkdm' is disabled. No return value. 231 * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or
232 * 0 upon success.
233 */
234static int _clkdm_del_wkdep(struct clockdomain *clkdm1,
235 struct clockdomain *clkdm2)
236{
237 struct clkdm_dep *cd;
238 int ret = 0;
239
240 if (!clkdm1 || !clkdm2)
241 return -EINVAL;
242
243 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
244 if (IS_ERR(cd))
245 ret = PTR_ERR(cd);
246
247 if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep)
248 ret = -EINVAL;
249
250 if (ret) {
251 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n",
252 clkdm1->name, clkdm2->name);
253 return ret;
254 }
255
256 cd->wkdep_usecount--;
257 if (cd->wkdep_usecount == 0) {
258 pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n",
259 clkdm1->name, clkdm2->name);
260
261 ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
262 }
263
264 return ret;
265}
266
267/**
268 * _clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 (lockless)
269 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
270 * @clkdm2: when this struct clockdomain * is active (source)
194 * 271 *
195 * XXX autodeps are deprecated and should be removed at the earliest 272 * Prevent @clkdm1 from automatically going inactive (and then to
196 * opportunity 273 * retention or off) if @clkdm2 is active. Returns -EINVAL if
274 * presented with invalid clockdomain pointers or called on a machine
275 * that does not support software-configurable hardware sleep
276 * dependencies, -ENOENT if the specified dependency cannot be set in
277 * hardware, or 0 upon success.
197 */ 278 */
198void _clkdm_del_autodeps(struct clockdomain *clkdm) 279static int _clkdm_add_sleepdep(struct clockdomain *clkdm1,
280 struct clockdomain *clkdm2)
199{ 281{
200 struct clkdm_autodep *autodep; 282 struct clkdm_dep *cd;
283 int ret = 0;
201 284
202 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) 285 if (!clkdm1 || !clkdm2)
203 return; 286 return -EINVAL;
204 287
205 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { 288 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
206 if (IS_ERR(autodep->clkdm.ptr)) 289 if (IS_ERR(cd))
207 continue; 290 ret = PTR_ERR(cd);
208 291
209 pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n", 292 if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep)
210 clkdm->name, autodep->clkdm.ptr->name); 293 ret = -EINVAL;
211 294
212 clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr); 295 if (ret) {
213 clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); 296 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n",
297 clkdm1->name, clkdm2->name);
298 return ret;
299 }
300
301 cd->sleepdep_usecount++;
302 if (cd->sleepdep_usecount == 1) {
303 pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n",
304 clkdm1->name, clkdm2->name);
305
306 ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
214 } 307 }
308
309 return ret;
215} 310}
216 311
217/** 312/**
218 * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms 313 * _clkdm_del_sleepdep - remove a sleep dep from clkdm2 to clkdm1 (lockless)
219 * @clkdm: clockdomain that we are resolving dependencies for 314 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
220 * @clkdm_deps: ptr to array of struct clkdm_deps to resolve 315 * @clkdm2: when this struct clockdomain * is active (source)
221 * 316 *
222 * Iterates through @clkdm_deps, looking up the struct clockdomain named by 317 * Allow @clkdm1 to automatically go inactive (and then to retention or
223 * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. 318 * off), independent of the activity state of @clkdm2. Returns -EINVAL
224 * No return value. 319 * if presented with invalid clockdomain pointers or called on a machine
320 * that does not support software-configurable hardware sleep dependencies,
321 * -ENOENT if the specified dependency cannot be cleared in hardware, or
322 * 0 upon success.
225 */ 323 */
226static void _resolve_clkdm_deps(struct clockdomain *clkdm, 324static int _clkdm_del_sleepdep(struct clockdomain *clkdm1,
227 struct clkdm_dep *clkdm_deps) 325 struct clockdomain *clkdm2)
228{ 326{
229 struct clkdm_dep *cd; 327 struct clkdm_dep *cd;
328 int ret = 0;
230 329
231 for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { 330 if (!clkdm1 || !clkdm2)
232 if (cd->clkdm) 331 return -EINVAL;
233 continue;
234 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
235 332
236 WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen", 333 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
237 clkdm->name, cd->clkdm_name); 334 if (IS_ERR(cd))
335 ret = PTR_ERR(cd);
336
337 if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep)
338 ret = -EINVAL;
339
340 if (ret) {
341 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n",
342 clkdm1->name, clkdm2->name);
343 return ret;
238 } 344 }
345
346 cd->sleepdep_usecount--;
347 if (cd->sleepdep_usecount == 0) {
348 pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n",
349 clkdm1->name, clkdm2->name);
350
351 ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
352 }
353
354 return ret;
239} 355}
240 356
241/* Public functions */ 357/* Public functions */
@@ -456,30 +572,18 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
456int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 572int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
457{ 573{
458 struct clkdm_dep *cd; 574 struct clkdm_dep *cd;
459 int ret = 0; 575 int ret;
460 576
461 if (!clkdm1 || !clkdm2) 577 if (!clkdm1 || !clkdm2)
462 return -EINVAL; 578 return -EINVAL;
463 579
464 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); 580 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
465 if (IS_ERR(cd)) 581 if (IS_ERR(cd))
466 ret = PTR_ERR(cd); 582 return PTR_ERR(cd);
467 583
468 if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) 584 pwrdm_lock(cd->clkdm->pwrdm.ptr);
469 ret = -EINVAL; 585 ret = _clkdm_add_wkdep(clkdm1, clkdm2);
470 586 pwrdm_unlock(cd->clkdm->pwrdm.ptr);
471 if (ret) {
472 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n",
473 clkdm1->name, clkdm2->name);
474 return ret;
475 }
476
477 if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
478 pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n",
479 clkdm1->name, clkdm2->name);
480
481 ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
482 }
483 587
484 return ret; 588 return ret;
485} 589}
@@ -497,30 +601,18 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
497int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 601int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
498{ 602{
499 struct clkdm_dep *cd; 603 struct clkdm_dep *cd;
500 int ret = 0; 604 int ret;
501 605
502 if (!clkdm1 || !clkdm2) 606 if (!clkdm1 || !clkdm2)
503 return -EINVAL; 607 return -EINVAL;
504 608
505 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); 609 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
506 if (IS_ERR(cd)) 610 if (IS_ERR(cd))
507 ret = PTR_ERR(cd); 611 return PTR_ERR(cd);
508 612
509 if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) 613 pwrdm_lock(cd->clkdm->pwrdm.ptr);
510 ret = -EINVAL; 614 ret = _clkdm_del_wkdep(clkdm1, clkdm2);
511 615 pwrdm_unlock(cd->clkdm->pwrdm.ptr);
512 if (ret) {
513 pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n",
514 clkdm1->name, clkdm2->name);
515 return ret;
516 }
517
518 if (atomic_dec_return(&cd->wkdep_usecount) == 0) {
519 pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n",
520 clkdm1->name, clkdm2->name);
521
522 ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
523 }
524 616
525 return ret; 617 return ret;
526} 618}
@@ -560,7 +652,7 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
560 return ret; 652 return ret;
561 } 653 }
562 654
563 /* XXX It's faster to return the atomic wkdep_usecount */ 655 /* XXX It's faster to return the wkdep_usecount */
564 return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2); 656 return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
565} 657}
566 658
@@ -600,30 +692,18 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
600int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 692int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
601{ 693{
602 struct clkdm_dep *cd; 694 struct clkdm_dep *cd;
603 int ret = 0; 695 int ret;
604 696
605 if (!clkdm1 || !clkdm2) 697 if (!clkdm1 || !clkdm2)
606 return -EINVAL; 698 return -EINVAL;
607 699
608 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); 700 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
609 if (IS_ERR(cd)) 701 if (IS_ERR(cd))
610 ret = PTR_ERR(cd); 702 return PTR_ERR(cd);
611 703
612 if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) 704 pwrdm_lock(cd->clkdm->pwrdm.ptr);
613 ret = -EINVAL; 705 ret = _clkdm_add_sleepdep(clkdm1, clkdm2);
614 706 pwrdm_unlock(cd->clkdm->pwrdm.ptr);
615 if (ret) {
616 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n",
617 clkdm1->name, clkdm2->name);
618 return ret;
619 }
620
621 if (atomic_inc_return(&cd->sleepdep_usecount) == 1) {
622 pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n",
623 clkdm1->name, clkdm2->name);
624
625 ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
626 }
627 707
628 return ret; 708 return ret;
629} 709}
@@ -643,30 +723,18 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
643int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) 723int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
644{ 724{
645 struct clkdm_dep *cd; 725 struct clkdm_dep *cd;
646 int ret = 0; 726 int ret;
647 727
648 if (!clkdm1 || !clkdm2) 728 if (!clkdm1 || !clkdm2)
649 return -EINVAL; 729 return -EINVAL;
650 730
651 cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); 731 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
652 if (IS_ERR(cd)) 732 if (IS_ERR(cd))
653 ret = PTR_ERR(cd); 733 return PTR_ERR(cd);
654 734
655 if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) 735 pwrdm_lock(cd->clkdm->pwrdm.ptr);
656 ret = -EINVAL; 736 ret = _clkdm_del_sleepdep(clkdm1, clkdm2);
657 737 pwrdm_unlock(cd->clkdm->pwrdm.ptr);
658 if (ret) {
659 pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n",
660 clkdm1->name, clkdm2->name);
661 return ret;
662 }
663
664 if (atomic_dec_return(&cd->sleepdep_usecount) == 0) {
665 pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n",
666 clkdm1->name, clkdm2->name);
667
668 ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
669 }
670 738
671 return ret; 739 return ret;
672} 740}
@@ -708,7 +776,7 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
708 return ret; 776 return ret;
709 } 777 }
710 778
711 /* XXX It's faster to return the atomic sleepdep_usecount */ 779 /* XXX It's faster to return the sleepdep_usecount */
712 return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2); 780 return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);
713} 781}
714 782
@@ -734,18 +802,17 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
734} 802}
735 803
736/** 804/**
737 * clkdm_sleep - force clockdomain sleep transition 805 * clkdm_sleep_nolock - force clockdomain sleep transition (lockless)
738 * @clkdm: struct clockdomain * 806 * @clkdm: struct clockdomain *
739 * 807 *
740 * Instruct the CM to force a sleep transition on the specified 808 * Instruct the CM to force a sleep transition on the specified
741 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if 809 * clockdomain @clkdm. Only for use by the powerdomain code. Returns
742 * clockdomain does not support software-initiated sleep; 0 upon 810 * -EINVAL if @clkdm is NULL or if clockdomain does not support
743 * success. 811 * software-initiated sleep; 0 upon success.
744 */ 812 */
745int clkdm_sleep(struct clockdomain *clkdm) 813int clkdm_sleep_nolock(struct clockdomain *clkdm)
746{ 814{
747 int ret; 815 int ret;
748 unsigned long flags;
749 816
750 if (!clkdm) 817 if (!clkdm)
751 return -EINVAL; 818 return -EINVAL;
@@ -761,26 +828,45 @@ int clkdm_sleep(struct clockdomain *clkdm)
761 828
762 pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); 829 pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
763 830
764 spin_lock_irqsave(&clkdm->lock, flags);
765 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; 831 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
766 ret = arch_clkdm->clkdm_sleep(clkdm); 832 ret = arch_clkdm->clkdm_sleep(clkdm);
767 spin_unlock_irqrestore(&clkdm->lock, flags); 833 ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
834
768 return ret; 835 return ret;
769} 836}
770 837
771/** 838/**
772 * clkdm_wakeup - force clockdomain wakeup transition 839 * clkdm_sleep - force clockdomain sleep transition
773 * @clkdm: struct clockdomain * 840 * @clkdm: struct clockdomain *
774 * 841 *
775 * Instruct the CM to force a wakeup transition on the specified 842 * Instruct the CM to force a sleep transition on the specified
776 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the 843 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if
777 * clockdomain does not support software-controlled wakeup; 0 upon 844 * clockdomain does not support software-initiated sleep; 0 upon
778 * success. 845 * success.
779 */ 846 */
780int clkdm_wakeup(struct clockdomain *clkdm) 847int clkdm_sleep(struct clockdomain *clkdm)
848{
849 int ret;
850
851 pwrdm_lock(clkdm->pwrdm.ptr);
852 ret = clkdm_sleep_nolock(clkdm);
853 pwrdm_unlock(clkdm->pwrdm.ptr);
854
855 return ret;
856}
857
858/**
859 * clkdm_wakeup_nolock - force clockdomain wakeup transition (lockless)
860 * @clkdm: struct clockdomain *
861 *
862 * Instruct the CM to force a wakeup transition on the specified
863 * clockdomain @clkdm. Only for use by the powerdomain code. Returns
864 * -EINVAL if @clkdm is NULL or if the clockdomain does not support
865 * software-controlled wakeup; 0 upon success.
866 */
867int clkdm_wakeup_nolock(struct clockdomain *clkdm)
781{ 868{
782 int ret; 869 int ret;
783 unsigned long flags;
784 870
785 if (!clkdm) 871 if (!clkdm)
786 return -EINVAL; 872 return -EINVAL;
@@ -796,28 +882,46 @@ int clkdm_wakeup(struct clockdomain *clkdm)
796 882
797 pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); 883 pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
798 884
799 spin_lock_irqsave(&clkdm->lock, flags);
800 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; 885 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
801 ret = arch_clkdm->clkdm_wakeup(clkdm); 886 ret = arch_clkdm->clkdm_wakeup(clkdm);
802 ret |= pwrdm_state_switch(clkdm->pwrdm.ptr); 887 ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
803 spin_unlock_irqrestore(&clkdm->lock, flags); 888
804 return ret; 889 return ret;
805} 890}
806 891
807/** 892/**
808 * clkdm_allow_idle - enable hwsup idle transitions for clkdm 893 * clkdm_wakeup - force clockdomain wakeup transition
809 * @clkdm: struct clockdomain * 894 * @clkdm: struct clockdomain *
810 * 895 *
811 * Allow the hardware to automatically switch the clockdomain @clkdm into 896 * Instruct the CM to force a wakeup transition on the specified
812 * active or idle states, as needed by downstream clocks. If the 897 * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the
898 * clockdomain does not support software-controlled wakeup; 0 upon
899 * success.
900 */
901int clkdm_wakeup(struct clockdomain *clkdm)
902{
903 int ret;
904
905 pwrdm_lock(clkdm->pwrdm.ptr);
906 ret = clkdm_wakeup_nolock(clkdm);
907 pwrdm_unlock(clkdm->pwrdm.ptr);
908
909 return ret;
910}
911
912/**
913 * clkdm_allow_idle_nolock - enable hwsup idle transitions for clkdm
914 * @clkdm: struct clockdomain *
915 *
916 * Allow the hardware to automatically switch the clockdomain @clkdm
917 * into active or idle states, as needed by downstream clocks. If the
813 * clockdomain has any downstream clocks enabled in the clock 918 * clockdomain has any downstream clocks enabled in the clock
814 * framework, wkdep/sleepdep autodependencies are added; this is so 919 * framework, wkdep/sleepdep autodependencies are added; this is so
815 * device drivers can read and write to the device. No return value. 920 * device drivers can read and write to the device. Only for use by
921 * the powerdomain code. No return value.
816 */ 922 */
817void clkdm_allow_idle(struct clockdomain *clkdm) 923void clkdm_allow_idle_nolock(struct clockdomain *clkdm)
818{ 924{
819 unsigned long flags;
820
821 if (!clkdm) 925 if (!clkdm)
822 return; 926 return;
823 927
@@ -833,11 +937,26 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
833 pr_debug("clockdomain: enabling automatic idle transitions for %s\n", 937 pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
834 clkdm->name); 938 clkdm->name);
835 939
836 spin_lock_irqsave(&clkdm->lock, flags);
837 clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED; 940 clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED;
838 arch_clkdm->clkdm_allow_idle(clkdm); 941 arch_clkdm->clkdm_allow_idle(clkdm);
839 pwrdm_state_switch(clkdm->pwrdm.ptr); 942 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
840 spin_unlock_irqrestore(&clkdm->lock, flags); 943}
944
945/**
946 * clkdm_allow_idle - enable hwsup idle transitions for clkdm
947 * @clkdm: struct clockdomain *
948 *
949 * Allow the hardware to automatically switch the clockdomain @clkdm into
950 * active or idle states, as needed by downstream clocks. If the
951 * clockdomain has any downstream clocks enabled in the clock
952 * framework, wkdep/sleepdep autodependencies are added; this is so
953 * device drivers can read and write to the device. No return value.
954 */
955void clkdm_allow_idle(struct clockdomain *clkdm)
956{
957 pwrdm_lock(clkdm->pwrdm.ptr);
958 clkdm_allow_idle_nolock(clkdm);
959 pwrdm_unlock(clkdm->pwrdm.ptr);
841} 960}
842 961
843/** 962/**
@@ -847,12 +966,11 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
847 * Prevent the hardware from automatically switching the clockdomain 966 * Prevent the hardware from automatically switching the clockdomain
848 * @clkdm into inactive or idle states. If the clockdomain has 967 * @clkdm into inactive or idle states. If the clockdomain has
849 * downstream clocks enabled in the clock framework, wkdep/sleepdep 968 * downstream clocks enabled in the clock framework, wkdep/sleepdep
850 * autodependencies are removed. No return value. 969 * autodependencies are removed. Only for use by the powerdomain
970 * code. No return value.
851 */ 971 */
852void clkdm_deny_idle(struct clockdomain *clkdm) 972void clkdm_deny_idle_nolock(struct clockdomain *clkdm)
853{ 973{
854 unsigned long flags;
855
856 if (!clkdm) 974 if (!clkdm)
857 return; 975 return;
858 976
@@ -868,11 +986,25 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
868 pr_debug("clockdomain: disabling automatic idle transitions for %s\n", 986 pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
869 clkdm->name); 987 clkdm->name);
870 988
871 spin_lock_irqsave(&clkdm->lock, flags);
872 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; 989 clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
873 arch_clkdm->clkdm_deny_idle(clkdm); 990 arch_clkdm->clkdm_deny_idle(clkdm);
874 pwrdm_state_switch(clkdm->pwrdm.ptr); 991 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
875 spin_unlock_irqrestore(&clkdm->lock, flags); 992}
993
994/**
995 * clkdm_deny_idle - disable hwsup idle transitions for clkdm
996 * @clkdm: struct clockdomain *
997 *
998 * Prevent the hardware from automatically switching the clockdomain
999 * @clkdm into inactive or idle states. If the clockdomain has
1000 * downstream clocks enabled in the clock framework, wkdep/sleepdep
1001 * autodependencies are removed. No return value.
1002 */
1003void clkdm_deny_idle(struct clockdomain *clkdm)
1004{
1005 pwrdm_lock(clkdm->pwrdm.ptr);
1006 clkdm_deny_idle_nolock(clkdm);
1007 pwrdm_unlock(clkdm->pwrdm.ptr);
876} 1008}
877 1009
878/** 1010/**
@@ -889,14 +1021,11 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
889bool clkdm_in_hwsup(struct clockdomain *clkdm) 1021bool clkdm_in_hwsup(struct clockdomain *clkdm)
890{ 1022{
891 bool ret; 1023 bool ret;
892 unsigned long flags;
893 1024
894 if (!clkdm) 1025 if (!clkdm)
895 return false; 1026 return false;
896 1027
897 spin_lock_irqsave(&clkdm->lock, flags);
898 ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; 1028 ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false;
899 spin_unlock_irqrestore(&clkdm->lock, flags);
900 1029
901 return ret; 1030 return ret;
902} 1031}
@@ -918,30 +1047,91 @@ bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
918 return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false; 1047 return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
919} 1048}
920 1049
1050/* Public autodep handling functions (deprecated) */
1051
1052/**
1053 * clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable
1054 * @clkdm: struct clockdomain *
1055 *
1056 * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm'
1057 * in hardware-supervised mode. Meant to be called from clock framework
1058 * when a clock inside clockdomain 'clkdm' is enabled. No return value.
1059 *
1060 * XXX autodeps are deprecated and should be removed at the earliest
1061 * opportunity
1062 */
1063void clkdm_add_autodeps(struct clockdomain *clkdm)
1064{
1065 struct clkdm_autodep *autodep;
1066
1067 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
1068 return;
1069
1070 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
1071 if (IS_ERR(autodep->clkdm.ptr))
1072 continue;
1073
1074 pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n",
1075 clkdm->name, autodep->clkdm.ptr->name);
1076
1077 _clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr);
1078 _clkdm_add_wkdep(clkdm, autodep->clkdm.ptr);
1079 }
1080}
1081
1082/**
1083 * clkdm_del_autodeps - remove auto sleepdeps/wkdeps from clkdm
1084 * @clkdm: struct clockdomain *
1085 *
1086 * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm'
1087 * in hardware-supervised mode. Meant to be called from clock framework
1088 * when a clock inside clockdomain 'clkdm' is disabled. No return value.
1089 *
1090 * XXX autodeps are deprecated and should be removed at the earliest
1091 * opportunity
1092 */
1093void clkdm_del_autodeps(struct clockdomain *clkdm)
1094{
1095 struct clkdm_autodep *autodep;
1096
1097 if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
1098 return;
1099
1100 for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
1101 if (IS_ERR(autodep->clkdm.ptr))
1102 continue;
1103
1104 pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n",
1105 clkdm->name, autodep->clkdm.ptr->name);
1106
1107 _clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr);
1108 _clkdm_del_wkdep(clkdm, autodep->clkdm.ptr);
1109 }
1110}
1111
921/* Clockdomain-to-clock/hwmod framework interface code */ 1112/* Clockdomain-to-clock/hwmod framework interface code */
922 1113
923static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) 1114static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
924{ 1115{
925 unsigned long flags;
926
927 if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) 1116 if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)
928 return -EINVAL; 1117 return -EINVAL;
929 1118
930 spin_lock_irqsave(&clkdm->lock, flags); 1119 pwrdm_lock(clkdm->pwrdm.ptr);
931 1120
932 /* 1121 /*
933 * For arch's with no autodeps, clkcm_clk_enable 1122 * For arch's with no autodeps, clkcm_clk_enable
934 * should be called for every clock instance or hwmod that is 1123 * should be called for every clock instance or hwmod that is
935 * enabled, so the clkdm can be force woken up. 1124 * enabled, so the clkdm can be force woken up.
936 */ 1125 */
937 if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) { 1126 clkdm->usecount++;
938 spin_unlock_irqrestore(&clkdm->lock, flags); 1127 if (clkdm->usecount > 1 && autodeps) {
1128 pwrdm_unlock(clkdm->pwrdm.ptr);
939 return 0; 1129 return 0;
940 } 1130 }
941 1131
942 arch_clkdm->clkdm_clk_enable(clkdm); 1132 arch_clkdm->clkdm_clk_enable(clkdm);
943 pwrdm_state_switch(clkdm->pwrdm.ptr); 1133 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
944 spin_unlock_irqrestore(&clkdm->lock, flags); 1134 pwrdm_unlock(clkdm->pwrdm.ptr);
945 1135
946 pr_debug("clockdomain: %s: enabled\n", clkdm->name); 1136 pr_debug("clockdomain: %s: enabled\n", clkdm->name);
947 1137
@@ -990,36 +1180,34 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
990 */ 1180 */
991int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) 1181int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
992{ 1182{
993 unsigned long flags;
994
995 if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) 1183 if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
996 return -EINVAL; 1184 return -EINVAL;
997 1185
998 spin_lock_irqsave(&clkdm->lock, flags); 1186 pwrdm_lock(clkdm->pwrdm.ptr);
999 1187
1000 /* corner case: disabling unused clocks */ 1188 /* corner case: disabling unused clocks */
1001 if ((__clk_get_enable_count(clk) == 0) && 1189 if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0)
1002 (atomic_read(&clkdm->usecount) == 0))
1003 goto ccd_exit; 1190 goto ccd_exit;
1004 1191
1005 if (atomic_read(&clkdm->usecount) == 0) { 1192 if (clkdm->usecount == 0) {
1006 spin_unlock_irqrestore(&clkdm->lock, flags); 1193 pwrdm_unlock(clkdm->pwrdm.ptr);
1007 WARN_ON(1); /* underflow */ 1194 WARN_ON(1); /* underflow */
1008 return -ERANGE; 1195 return -ERANGE;
1009 } 1196 }
1010 1197
1011 if (atomic_dec_return(&clkdm->usecount) > 0) { 1198 clkdm->usecount--;
1012 spin_unlock_irqrestore(&clkdm->lock, flags); 1199 if (clkdm->usecount > 0) {
1200 pwrdm_unlock(clkdm->pwrdm.ptr);
1013 return 0; 1201 return 0;
1014 } 1202 }
1015 1203
1016 arch_clkdm->clkdm_clk_disable(clkdm); 1204 arch_clkdm->clkdm_clk_disable(clkdm);
1017 pwrdm_state_switch(clkdm->pwrdm.ptr); 1205 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
1018 1206
1019 pr_debug("clockdomain: %s: disabled\n", clkdm->name); 1207 pr_debug("clockdomain: %s: disabled\n", clkdm->name);
1020 1208
1021ccd_exit: 1209ccd_exit:
1022 spin_unlock_irqrestore(&clkdm->lock, flags); 1210 pwrdm_unlock(clkdm->pwrdm.ptr);
1023 1211
1024 return 0; 1212 return 0;
1025} 1213}
@@ -1072,8 +1260,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
1072 */ 1260 */
1073int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) 1261int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
1074{ 1262{
1075 unsigned long flags;
1076
1077 /* The clkdm attribute does not exist yet prior OMAP4 */ 1263 /* The clkdm attribute does not exist yet prior OMAP4 */
1078 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 1264 if (cpu_is_omap24xx() || cpu_is_omap34xx())
1079 return 0; 1265 return 0;
@@ -1086,22 +1272,23 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
1086 if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) 1272 if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
1087 return -EINVAL; 1273 return -EINVAL;
1088 1274
1089 spin_lock_irqsave(&clkdm->lock, flags); 1275 pwrdm_lock(clkdm->pwrdm.ptr);
1090 1276
1091 if (atomic_read(&clkdm->usecount) == 0) { 1277 if (clkdm->usecount == 0) {
1092 spin_unlock_irqrestore(&clkdm->lock, flags); 1278 pwrdm_unlock(clkdm->pwrdm.ptr);
1093 WARN_ON(1); /* underflow */ 1279 WARN_ON(1); /* underflow */
1094 return -ERANGE; 1280 return -ERANGE;
1095 } 1281 }
1096 1282
1097 if (atomic_dec_return(&clkdm->usecount) > 0) { 1283 clkdm->usecount--;
1098 spin_unlock_irqrestore(&clkdm->lock, flags); 1284 if (clkdm->usecount > 0) {
1285 pwrdm_unlock(clkdm->pwrdm.ptr);
1099 return 0; 1286 return 0;
1100 } 1287 }
1101 1288
1102 arch_clkdm->clkdm_clk_disable(clkdm); 1289 arch_clkdm->clkdm_clk_disable(clkdm);
1103 pwrdm_state_switch(clkdm->pwrdm.ptr); 1290 pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
1104 spin_unlock_irqrestore(&clkdm->lock, flags); 1291 pwrdm_unlock(clkdm->pwrdm.ptr);
1105 1292
1106 pr_debug("clockdomain: %s: disabled\n", clkdm->name); 1293 pr_debug("clockdomain: %s: disabled\n", clkdm->name);
1107 1294
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index bc42446e23ab..2da37656a693 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -15,7 +15,6 @@
15#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H 15#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H
16 16
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/spinlock.h>
19 18
20#include "powerdomain.h" 19#include "powerdomain.h"
21#include "clock.h" 20#include "clock.h"
@@ -92,8 +91,8 @@ struct clkdm_autodep {
92struct clkdm_dep { 91struct clkdm_dep {
93 const char *clkdm_name; 92 const char *clkdm_name;
94 struct clockdomain *clkdm; 93 struct clockdomain *clkdm;
95 atomic_t wkdep_usecount; 94 s16 wkdep_usecount;
96 atomic_t sleepdep_usecount; 95 s16 sleepdep_usecount;
97}; 96};
98 97
99/* Possible flags for struct clockdomain._flags */ 98/* Possible flags for struct clockdomain._flags */
@@ -137,9 +136,8 @@ struct clockdomain {
137 const u16 clkdm_offs; 136 const u16 clkdm_offs;
138 struct clkdm_dep *wkdep_srcs; 137 struct clkdm_dep *wkdep_srcs;
139 struct clkdm_dep *sleepdep_srcs; 138 struct clkdm_dep *sleepdep_srcs;
140 atomic_t usecount; 139 int usecount;
141 struct list_head node; 140 struct list_head node;
142 spinlock_t lock;
143}; 141};
144 142
145/** 143/**
@@ -196,12 +194,16 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
196int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); 194int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
197int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); 195int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
198 196
197void clkdm_allow_idle_nolock(struct clockdomain *clkdm);
199void clkdm_allow_idle(struct clockdomain *clkdm); 198void clkdm_allow_idle(struct clockdomain *clkdm);
199void clkdm_deny_idle_nolock(struct clockdomain *clkdm);
200void clkdm_deny_idle(struct clockdomain *clkdm); 200void clkdm_deny_idle(struct clockdomain *clkdm);
201bool clkdm_in_hwsup(struct clockdomain *clkdm); 201bool clkdm_in_hwsup(struct clockdomain *clkdm);
202bool clkdm_missing_idle_reporting(struct clockdomain *clkdm); 202bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
203 203
204int clkdm_wakeup_nolock(struct clockdomain *clkdm);
204int clkdm_wakeup(struct clockdomain *clkdm); 205int clkdm_wakeup(struct clockdomain *clkdm);
206int clkdm_sleep_nolock(struct clockdomain *clkdm);
205int clkdm_sleep(struct clockdomain *clkdm); 207int clkdm_sleep(struct clockdomain *clkdm);
206 208
207int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); 209int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
@@ -214,8 +216,9 @@ extern void __init omap243x_clockdomains_init(void);
214extern void __init omap3xxx_clockdomains_init(void); 216extern void __init omap3xxx_clockdomains_init(void);
215extern void __init am33xx_clockdomains_init(void); 217extern void __init am33xx_clockdomains_init(void);
216extern void __init omap44xx_clockdomains_init(void); 218extern void __init omap44xx_clockdomains_init(void);
217extern void _clkdm_add_autodeps(struct clockdomain *clkdm); 219
218extern void _clkdm_del_autodeps(struct clockdomain *clkdm); 220extern void clkdm_add_autodeps(struct clockdomain *clkdm);
221extern void clkdm_del_autodeps(struct clockdomain *clkdm);
219 222
220extern struct clkdm_ops omap2_clkdm_operations; 223extern struct clkdm_ops omap2_clkdm_operations;
221extern struct clkdm_ops omap3_clkdm_operations; 224extern struct clkdm_ops omap3_clkdm_operations;
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index db650690e9d0..6774a53a3874 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -273,9 +273,6 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
273 273
274static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm) 274static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
275{ 275{
276 if (atomic_read(&clkdm->usecount) > 0)
277 _clkdm_add_autodeps(clkdm);
278
279 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, 276 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
280 clkdm->clktrctrl_mask); 277 clkdm->clktrctrl_mask);
281} 278}
@@ -284,9 +281,6 @@ static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
284{ 281{
285 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, 282 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
286 clkdm->clktrctrl_mask); 283 clkdm->clktrctrl_mask);
287
288 if (atomic_read(&clkdm->usecount) > 0)
289 _clkdm_del_autodeps(clkdm);
290} 284}
291 285
292static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) 286static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
@@ -298,18 +292,8 @@ static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
298 292
299 hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, 293 hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
300 clkdm->clktrctrl_mask); 294 clkdm->clktrctrl_mask);
301 295 if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
302 if (hwsup) { 296 omap2xxx_clkdm_wakeup(clkdm);
303 /* Disable HW transitions when we are changing deps */
304 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
305 clkdm->clktrctrl_mask);
306 _clkdm_add_autodeps(clkdm);
307 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
308 clkdm->clktrctrl_mask);
309 } else {
310 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
311 omap2xxx_clkdm_wakeup(clkdm);
312 }
313 297
314 return 0; 298 return 0;
315} 299}
@@ -324,17 +308,8 @@ static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
324 hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, 308 hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
325 clkdm->clktrctrl_mask); 309 clkdm->clktrctrl_mask);
326 310
327 if (hwsup) { 311 if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
328 /* Disable HW transitions when we are changing deps */ 312 omap2xxx_clkdm_sleep(clkdm);
329 omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
330 clkdm->clktrctrl_mask);
331 _clkdm_del_autodeps(clkdm);
332 omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
333 clkdm->clktrctrl_mask);
334 } else {
335 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
336 omap2xxx_clkdm_sleep(clkdm);
337 }
338 313
339 return 0; 314 return 0;
340} 315}
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index c2086f2e86b6..9061c307d915 100644
--- a/arch/arm/mach-omap2/cm3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -186,7 +186,7 @@ static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
186 continue; /* only happens if data is erroneous */ 186 continue; /* only happens if data is erroneous */
187 187
188 mask |= 1 << cd->clkdm->dep_bit; 188 mask |= 1 << cd->clkdm->dep_bit;
189 atomic_set(&cd->sleepdep_usecount, 0); 189 cd->sleepdep_usecount = 0;
190 } 190 }
191 omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, 191 omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
192 OMAP3430_CM_SLEEPDEP); 192 OMAP3430_CM_SLEEPDEP);
@@ -209,8 +209,8 @@ static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
209 209
210static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm) 210static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
211{ 211{
212 if (atomic_read(&clkdm->usecount) > 0) 212 if (clkdm->usecount > 0)
213 _clkdm_add_autodeps(clkdm); 213 clkdm_add_autodeps(clkdm);
214 214
215 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, 215 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
216 clkdm->clktrctrl_mask); 216 clkdm->clktrctrl_mask);
@@ -221,8 +221,8 @@ static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
221 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, 221 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
222 clkdm->clktrctrl_mask); 222 clkdm->clktrctrl_mask);
223 223
224 if (atomic_read(&clkdm->usecount) > 0) 224 if (clkdm->usecount > 0)
225 _clkdm_del_autodeps(clkdm); 225 clkdm_del_autodeps(clkdm);
226} 226}
227 227
228static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) 228static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
@@ -250,7 +250,7 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
250 /* Disable HW transitions when we are changing deps */ 250 /* Disable HW transitions when we are changing deps */
251 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, 251 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
252 clkdm->clktrctrl_mask); 252 clkdm->clktrctrl_mask);
253 _clkdm_add_autodeps(clkdm); 253 clkdm_add_autodeps(clkdm);
254 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, 254 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
255 clkdm->clktrctrl_mask); 255 clkdm->clktrctrl_mask);
256 } else { 256 } else {
@@ -287,7 +287,7 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
287 /* Disable HW transitions when we are changing deps */ 287 /* Disable HW transitions when we are changing deps */
288 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, 288 omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
289 clkdm->clktrctrl_mask); 289 clkdm->clktrctrl_mask);
290 _clkdm_del_autodeps(clkdm); 290 clkdm_del_autodeps(clkdm);
291 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, 291 omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
292 clkdm->clktrctrl_mask); 292 clkdm->clktrctrl_mask);
293 } else { 293 } else {
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 7f9a464f01e9..f0290f5566fe 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -393,7 +393,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
393 continue; /* only happens if data is erroneous */ 393 continue; /* only happens if data is erroneous */
394 394
395 mask |= 1 << cd->clkdm->dep_bit; 395 mask |= 1 << cd->clkdm->dep_bit;
396 atomic_set(&cd->wkdep_usecount, 0); 396 cd->wkdep_usecount = 0;
397 } 397 }
398 398
399 omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, 399 omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 22590dbe8f14..80392fca86c6 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -36,40 +36,66 @@
36 36
37/* Mach specific information to be recorded in the C-state driver_data */ 37/* Mach specific information to be recorded in the C-state driver_data */
38struct omap3_idle_statedata { 38struct omap3_idle_statedata {
39 u32 mpu_state; 39 u8 mpu_state;
40 u32 core_state; 40 u8 core_state;
41 u8 per_min_state;
42 u8 flags;
41}; 43};
42 44
43static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; 45static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
44 46
47/*
48 * Possible flag bits for struct omap3_idle_statedata.flags:
49 *
50 * OMAP_CPUIDLE_CX_NO_CLKDM_IDLE: don't allow the MPU clockdomain to go
51 * inactive. This in turn prevents the MPU DPLL from entering autoidle
52 * mode, so wakeup latency is greatly reduced, at the cost of additional
53 * energy consumption. This also prevents the CORE clockdomain from
54 * entering idle.
55 */
56#define OMAP_CPUIDLE_CX_NO_CLKDM_IDLE BIT(0)
57
58/*
59 * Prevent PER OFF if CORE is not in RETention or OFF as this would
60 * disable PER wakeups completely.
61 */
45static struct omap3_idle_statedata omap3_idle_data[] = { 62static struct omap3_idle_statedata omap3_idle_data[] = {
46 { 63 {
47 .mpu_state = PWRDM_POWER_ON, 64 .mpu_state = PWRDM_POWER_ON,
48 .core_state = PWRDM_POWER_ON, 65 .core_state = PWRDM_POWER_ON,
66 /* In C1 do not allow PER state lower than CORE state */
67 .per_min_state = PWRDM_POWER_ON,
68 .flags = OMAP_CPUIDLE_CX_NO_CLKDM_IDLE,
49 }, 69 },
50 { 70 {
51 .mpu_state = PWRDM_POWER_ON, 71 .mpu_state = PWRDM_POWER_ON,
52 .core_state = PWRDM_POWER_ON, 72 .core_state = PWRDM_POWER_ON,
73 .per_min_state = PWRDM_POWER_RET,
53 }, 74 },
54 { 75 {
55 .mpu_state = PWRDM_POWER_RET, 76 .mpu_state = PWRDM_POWER_RET,
56 .core_state = PWRDM_POWER_ON, 77 .core_state = PWRDM_POWER_ON,
78 .per_min_state = PWRDM_POWER_RET,
57 }, 79 },
58 { 80 {
59 .mpu_state = PWRDM_POWER_OFF, 81 .mpu_state = PWRDM_POWER_OFF,
60 .core_state = PWRDM_POWER_ON, 82 .core_state = PWRDM_POWER_ON,
83 .per_min_state = PWRDM_POWER_RET,
61 }, 84 },
62 { 85 {
63 .mpu_state = PWRDM_POWER_RET, 86 .mpu_state = PWRDM_POWER_RET,
64 .core_state = PWRDM_POWER_RET, 87 .core_state = PWRDM_POWER_RET,
88 .per_min_state = PWRDM_POWER_OFF,
65 }, 89 },
66 { 90 {
67 .mpu_state = PWRDM_POWER_OFF, 91 .mpu_state = PWRDM_POWER_OFF,
68 .core_state = PWRDM_POWER_RET, 92 .core_state = PWRDM_POWER_RET,
93 .per_min_state = PWRDM_POWER_OFF,
69 }, 94 },
70 { 95 {
71 .mpu_state = PWRDM_POWER_OFF, 96 .mpu_state = PWRDM_POWER_OFF,
72 .core_state = PWRDM_POWER_OFF, 97 .core_state = PWRDM_POWER_OFF,
98 .per_min_state = PWRDM_POWER_OFF,
73 }, 99 },
74}; 100};
75 101
@@ -80,27 +106,25 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
80 int index) 106 int index)
81{ 107{
82 struct omap3_idle_statedata *cx = &omap3_idle_data[index]; 108 struct omap3_idle_statedata *cx = &omap3_idle_data[index];
83 u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
84 109
85 local_fiq_disable(); 110 local_fiq_disable();
86 111
87 pwrdm_set_next_pwrst(mpu_pd, mpu_state);
88 pwrdm_set_next_pwrst(core_pd, core_state);
89
90 if (omap_irq_pending() || need_resched()) 112 if (omap_irq_pending() || need_resched())
91 goto return_sleep_time; 113 goto return_sleep_time;
92 114
93 /* Deny idle for C1 */ 115 /* Deny idle for C1 */
94 if (index == 0) { 116 if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) {
95 clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]); 117 clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]);
96 clkdm_deny_idle(core_pd->pwrdm_clkdms[0]); 118 } else {
119 pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
120 pwrdm_set_next_pwrst(core_pd, cx->core_state);
97 } 121 }
98 122
99 /* 123 /*
100 * Call idle CPU PM enter notifier chain so that 124 * Call idle CPU PM enter notifier chain so that
101 * VFP context is saved. 125 * VFP context is saved.
102 */ 126 */
103 if (mpu_state == PWRDM_POWER_OFF) 127 if (cx->mpu_state == PWRDM_POWER_OFF)
104 cpu_pm_enter(); 128 cpu_pm_enter();
105 129
106 /* Execute ARM wfi */ 130 /* Execute ARM wfi */
@@ -110,17 +134,15 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
110 * Call idle CPU PM enter notifier chain to restore 134 * Call idle CPU PM enter notifier chain to restore
111 * VFP context. 135 * VFP context.
112 */ 136 */
113 if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) 137 if (cx->mpu_state == PWRDM_POWER_OFF &&
138 pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
114 cpu_pm_exit(); 139 cpu_pm_exit();
115 140
116 /* Re-allow idle for C1 */ 141 /* Re-allow idle for C1 */
117 if (index == 0) { 142 if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE)
118 clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); 143 clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]);
119 clkdm_allow_idle(core_pd->pwrdm_clkdms[0]);
120 }
121 144
122return_sleep_time: 145return_sleep_time:
123
124 local_fiq_enable(); 146 local_fiq_enable();
125 147
126 return index; 148 return index;
@@ -185,7 +207,7 @@ static int next_valid_state(struct cpuidle_device *dev,
185 * Start search from the next (lower) state. 207 * Start search from the next (lower) state.
186 */ 208 */
187 for (idx = index - 1; idx >= 0; idx--) { 209 for (idx = index - 1; idx >= 0; idx--) {
188 cx = &omap3_idle_data[idx]; 210 cx = &omap3_idle_data[idx];
189 if ((cx->mpu_state >= mpu_deepest_state) && 211 if ((cx->mpu_state >= mpu_deepest_state) &&
190 (cx->core_state >= core_deepest_state)) { 212 (cx->core_state >= core_deepest_state)) {
191 next_index = idx; 213 next_index = idx;
@@ -209,10 +231,9 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
209 struct cpuidle_driver *drv, 231 struct cpuidle_driver *drv,
210 int index) 232 int index)
211{ 233{
212 int new_state_idx; 234 int new_state_idx, ret;
213 u32 core_next_state, per_next_state = 0, per_saved_state = 0; 235 u8 per_next_state, per_saved_state;
214 struct omap3_idle_statedata *cx; 236 struct omap3_idle_statedata *cx;
215 int ret;
216 237
217 /* 238 /*
218 * Use only C1 if CAM is active. 239 * Use only C1 if CAM is active.
@@ -233,25 +254,13 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
233 254
234 /* Program PER state */ 255 /* Program PER state */
235 cx = &omap3_idle_data[new_state_idx]; 256 cx = &omap3_idle_data[new_state_idx];
236 core_next_state = cx->core_state;
237 per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
238 if (new_state_idx == 0) {
239 /* In C1 do not allow PER state lower than CORE state */
240 if (per_next_state < core_next_state)
241 per_next_state = core_next_state;
242 } else {
243 /*
244 * Prevent PER OFF if CORE is not in RETention or OFF as this
245 * would disable PER wakeups completely.
246 */
247 if ((per_next_state == PWRDM_POWER_OFF) &&
248 (core_next_state > PWRDM_POWER_RET))
249 per_next_state = PWRDM_POWER_RET;
250 }
251 257
252 /* Are we changing PER target state? */ 258 per_next_state = pwrdm_read_next_pwrst(per_pd);
253 if (per_next_state != per_saved_state) 259 per_saved_state = per_next_state;
260 if (per_next_state < cx->per_min_state) {
261 per_next_state = cx->per_min_state;
254 pwrdm_set_next_pwrst(per_pd, per_next_state); 262 pwrdm_set_next_pwrst(per_pd, per_next_state);
263 }
255 264
256 ret = omap3_enter_idle(dev, drv, new_state_idx); 265 ret = omap3_enter_idle(dev, drv, new_state_idx);
257 266
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 342d69399ec7..142d9c616f1b 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -62,8 +62,7 @@ static int __init omap3_l3_init(void)
62 if (!oh) 62 if (!oh)
63 pr_err("could not look up %s\n", oh_name); 63 pr_err("could not look up %s\n", oh_name);
64 64
65 pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0, 65 pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0);
66 NULL, 0, 0);
67 66
68 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); 67 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
69 68
@@ -97,8 +96,7 @@ static int __init omap4_l3_init(void)
97 pr_err("could not look up %s\n", oh_name); 96 pr_err("could not look up %s\n", oh_name);
98 } 97 }
99 98
100 pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, 99 pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, 0);
101 0, NULL, 0, 0);
102 100
103 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); 101 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
104 102
@@ -317,7 +315,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data
317 keypad_data = sdp4430_keypad_data; 315 keypad_data = sdp4430_keypad_data;
318 316
319 pdev = omap_device_build(name, id, oh, keypad_data, 317 pdev = omap_device_build(name, id, oh, keypad_data,
320 sizeof(struct omap4_keypad_platform_data), NULL, 0, 0); 318 sizeof(struct omap4_keypad_platform_data));
321 319
322 if (IS_ERR(pdev)) { 320 if (IS_ERR(pdev)) {
323 WARN(1, "Can't build omap_device for %s:%s.\n", 321 WARN(1, "Can't build omap_device for %s:%s.\n",
@@ -341,7 +339,7 @@ static inline void __init omap_init_mbox(void)
341 return; 339 return;
342 } 340 }
343 341
344 pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0); 342 pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0);
345 WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", 343 WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
346 __func__, PTR_ERR(pdev)); 344 __func__, PTR_ERR(pdev));
347} 345}
@@ -381,7 +379,7 @@ static void __init omap_init_mcpdm(void)
381 return; 379 return;
382 } 380 }
383 381
384 pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0, NULL, 0, 0); 382 pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0);
385 WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n"); 383 WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n");
386} 384}
387#else 385#else
@@ -402,7 +400,7 @@ static void __init omap_init_dmic(void)
402 return; 400 return;
403 } 401 }
404 402
405 pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0); 403 pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0);
406 WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n"); 404 WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n");
407} 405}
408#else 406#else
@@ -428,8 +426,7 @@ static void __init omap_init_hdmi_audio(void)
428 return; 426 return;
429 } 427 }
430 428
431 pdev = omap_device_build("omap-hdmi-audio-dai", 429 pdev = omap_device_build("omap-hdmi-audio-dai", -1, oh, NULL, 0, 0);
432 -1, oh, NULL, 0, NULL, 0, 0);
433 WARN(IS_ERR(pdev), 430 WARN(IS_ERR(pdev),
434 "Can't build omap_device for omap-hdmi-audio-dai.\n"); 431 "Can't build omap_device for omap-hdmi-audio-dai.\n");
435 432
@@ -473,8 +470,7 @@ static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused)
473 } 470 }
474 471
475 spi_num++; 472 spi_num++;
476 pdev = omap_device_build(name, spi_num, oh, pdata, 473 pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata));
477 sizeof(*pdata), NULL, 0, 0);
478 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", 474 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n",
479 name, oh->name); 475 name, oh->name);
480 kfree(pdata); 476 kfree(pdata);
@@ -504,7 +500,7 @@ static void omap_init_rng(void)
504 if (!oh) 500 if (!oh)
505 return; 501 return;
506 502
507 pdev = omap_device_build("omap_rng", -1, oh, NULL, 0, NULL, 0, 0); 503 pdev = omap_device_build("omap_rng", -1, oh, NULL, 0);
508 WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); 504 WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");
509} 505}
510 506
@@ -733,8 +729,7 @@ static void __init omap_init_ocp2scp(void)
733 729
734 pdata->dev_cnt = dev_cnt; 730 pdata->dev_cnt = dev_cnt;
735 731
736 pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, 732 pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata));
737 0, false);
738 if (IS_ERR(pdev)) { 733 if (IS_ERR(pdev)) {
739 pr_err("Could not build omap_device for %s %s\n", 734 pr_err("Could not build omap_device for %s %s\n",
740 name, oh_name); 735 name, oh_name);
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index cc75aaf6e764..ff37be1f6f93 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -226,7 +226,7 @@ static struct platform_device *create_dss_pdev(const char *pdev_name,
226 dev_set_name(&pdev->dev, "%s", pdev->name); 226 dev_set_name(&pdev->dev, "%s", pdev->name);
227 227
228 ohs[0] = oh; 228 ohs[0] = oh;
229 od = omap_device_alloc(pdev, ohs, 1, NULL, 0); 229 od = omap_device_alloc(pdev, ohs, 1);
230 if (IS_ERR(od)) { 230 if (IS_ERR(od)) {
231 pr_err("Could not alloc omap_device for %s\n", pdev_name); 231 pr_err("Could not alloc omap_device for %s\n", pdev_name);
232 r = -ENOMEM; 232 r = -ENOMEM;
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 5cd8d7668bec..dab9fc014b97 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -248,7 +248,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
248 248
249 p->errata = configure_dma_errata(); 249 p->errata = configure_dma_errata();
250 250
251 pdev = omap_device_build(name, 0, oh, p, sizeof(*p), NULL, 0, 0); 251 pdev = omap_device_build(name, 0, oh, p, sizeof(*p));
252 kfree(p); 252 kfree(p);
253 if (IS_ERR(pdev)) { 253 if (IS_ERR(pdev)) {
254 pr_err("%s: Can't build omap_device for %s:%s.\n", 254 pr_err("%s: Can't build omap_device for %s:%s.\n",
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
index 231ed5f2bc81..59a4af779f42 100644
--- a/arch/arm/mach-omap2/drm.c
+++ b/arch/arm/mach-omap2/drm.c
@@ -51,8 +51,7 @@ static int __init omap_init_drm(void)
51 oh = omap_hwmod_lookup("dmm"); 51 oh = omap_hwmod_lookup("dmm");
52 52
53 if (oh) { 53 if (oh) {
54 pdev = omap_device_build(oh->name, -1, oh, NULL, 0, NULL, 0, 54 pdev = omap_device_build(oh->name, -1, oh, NULL, 0);
55 false);
56 WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", 55 WARN(IS_ERR(pdev), "Could not build omap_device for %s\n",
57 oh->name); 56 oh->name);
58 } 57 }
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 40950f5af1f0..7a577145b68b 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -132,8 +132,7 @@ static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
132 pwrdm = omap_hwmod_get_pwrdm(oh); 132 pwrdm = omap_hwmod_get_pwrdm(oh);
133 pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); 133 pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
134 134
135 pdev = omap_device_build(name, id - 1, oh, pdata, 135 pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata));
136 sizeof(*pdata), NULL, 0, false);
137 kfree(pdata); 136 kfree(pdata);
138 137
139 if (IS_ERR(pdev)) { 138 if (IS_ERR(pdev)) {
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 7911e2824899..8d70bd03c5d8 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1448,7 +1448,7 @@ static int __init omap_gpmc_init(void)
1448 return -ENODEV; 1448 return -ENODEV;
1449 } 1449 }
1450 1450
1451 pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0, NULL, 0, 0); 1451 pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0);
1452 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); 1452 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
1453 1453
1454 return IS_ERR(pdev) ? PTR_ERR(pdev) : 0; 1454 return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c
index f6e0e7e68f9f..cbc8e3c480e0 100644
--- a/arch/arm/mach-omap2/hdq1w.c
+++ b/arch/arm/mach-omap2/hdq1w.c
@@ -88,7 +88,7 @@ static int __init omap_init_hdq(void)
88 if (!oh) 88 if (!oh)
89 return 0; 89 return 0;
90 90
91 pdev = omap_device_build(devname, id, oh, NULL, 0, NULL, 0, 0); 91 pdev = omap_device_build(devname, id, oh, NULL, 0);
92 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", 92 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
93 devname, oh->name); 93 devname, oh->name);
94 94
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 4a964338992a..2ef1f8714fcf 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -522,7 +522,7 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
522 } 522 }
523 dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); 523 dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
524 524
525 od = omap_device_alloc(pdev, ohs, 1, NULL, 0); 525 od = omap_device_alloc(pdev, ohs, 1);
526 if (IS_ERR(od)) { 526 if (IS_ERR(od)) {
527 pr_err("Could not allocate od for %s\n", name); 527 pr_err("Could not allocate od for %s\n", name);
528 goto put_pdev; 528 goto put_pdev;
diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c
index bcb357e948b7..ef175acaeaa2 100644
--- a/arch/arm/mach-omap2/hwspinlock.c
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -47,8 +47,7 @@ static int __init hwspinlocks_init(void)
47 return -EINVAL; 47 return -EINVAL;
48 48
49 pdev = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata, 49 pdev = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata,
50 sizeof(struct hwspinlock_pdata), 50 sizeof(struct hwspinlock_pdata));
51 NULL, 0, false);
52 if (IS_ERR(pdev)) { 51 if (IS_ERR(pdev)) {
53 pr_err("Can't build omap_device for %s:%s\n", dev_name, 52 pr_err("Can't build omap_device for %s:%s\n", dev_name,
54 oh_name); 53 oh_name);
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c
index 8fd98576f4d3..d940e53dd9f2 100644
--- a/arch/arm/mach-omap2/i2c.c
+++ b/arch/arm/mach-omap2/i2c.c
@@ -178,8 +178,7 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata,
178 if (cpu_is_omap34xx()) 178 if (cpu_is_omap34xx())
179 pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; 179 pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
180 pdev = omap_device_build(name, bus_id, oh, pdata, 180 pdev = omap_device_build(name, bus_id, oh, pdata,
181 sizeof(struct omap_i2c_bus_platform_data), 181 sizeof(struct omap_i2c_bus_platform_data));
182 NULL, 0, 0);
183 WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); 182 WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name);
184 183
185 return PTR_RET(pdev); 184 return PTR_RET(pdev);
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 1c0968db43bf..5d8768075dd9 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -102,7 +102,7 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
102 count++; 102 count++;
103 } 103 }
104 pdev = omap_device_build_ss(name, id, oh_device, count, pdata, 104 pdev = omap_device_build_ss(name, id, oh_device, count, pdata,
105 sizeof(*pdata), NULL, 0, false); 105 sizeof(*pdata));
106 kfree(pdata); 106 kfree(pdata);
107 if (IS_ERR(pdev)) { 107 if (IS_ERR(pdev)) {
108 pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, 108 pr_err("%s: Can't build omap_device for %s:%s.\n", __func__,
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c
index aafdd4ca9f4f..c52d8b4a3e91 100644
--- a/arch/arm/mach-omap2/msdi.c
+++ b/arch/arm/mach-omap2/msdi.c
@@ -150,7 +150,7 @@ void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
150 return; 150 return;
151 } 151 }
152 pdev = omap_device_build(dev_name, id, oh, mmc_data[0], 152 pdev = omap_device_build(dev_name, id, oh, mmc_data[0],
153 sizeof(struct omap_mmc_platform_data), NULL, 0, 0); 153 sizeof(struct omap_mmc_platform_data));
154 if (IS_ERR(pdev)) 154 if (IS_ERR(pdev))
155 WARN(1, "Can'd build omap_device for %s:%s.\n", 155 WARN(1, "Can'd build omap_device for %s:%s.\n",
156 dev_name, oh->name); 156 dev_name, oh->name);
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index c20423955bf7..f6daae821ebb 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -42,8 +42,7 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
42 pdata->deassert_reset = omap_device_deassert_hardreset; 42 pdata->deassert_reset = omap_device_deassert_hardreset;
43 } 43 }
44 44
45 pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata), 45 pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata));
46 NULL, 0, 0);
47 46
48 kfree(pdata); 47 kfree(pdata);
49 48
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index aac46bfdbeb2..8bcb64bcdcdb 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -87,37 +87,6 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
87} 87}
88 88
89/* 89/*
90 * Set the CPUx powerdomain's previous power state
91 */
92static inline void set_cpu_next_pwrst(unsigned int cpu_id,
93 unsigned int power_state)
94{
95 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
96
97 pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
98}
99
100/*
101 * Read CPU's previous power state
102 */
103static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id)
104{
105 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
106
107 return pwrdm_read_prev_pwrst(pm_info->pwrdm);
108}
109
110/*
111 * Clear the CPUx powerdomain's previous power state
112 */
113static inline void clear_cpu_prev_pwrst(unsigned int cpu_id)
114{
115 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
116
117 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
118}
119
120/*
121 * Store the SCU power status value to scratchpad memory 90 * Store the SCU power status value to scratchpad memory
122 */ 91 */
123static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) 92static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
@@ -230,6 +199,7 @@ static void save_l2x0_context(void)
230 */ 199 */
231int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) 200int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
232{ 201{
202 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
233 unsigned int save_state = 0; 203 unsigned int save_state = 0;
234 unsigned int wakeup_cpu; 204 unsigned int wakeup_cpu;
235 205
@@ -268,7 +238,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
268 save_state = 2; 238 save_state = 2;
269 239
270 cpu_clear_prev_logic_pwrst(cpu); 240 cpu_clear_prev_logic_pwrst(cpu);
271 set_cpu_next_pwrst(cpu, power_state); 241 pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
272 set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); 242 set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
273 scu_pwrst_prepare(cpu, power_state); 243 scu_pwrst_prepare(cpu, power_state);
274 l2x0_pwrst_prepare(cpu, save_state); 244 l2x0_pwrst_prepare(cpu, save_state);
@@ -286,7 +256,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
286 * domain transition 256 * domain transition
287 */ 257 */
288 wakeup_cpu = smp_processor_id(); 258 wakeup_cpu = smp_processor_id();
289 set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); 259 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
290 260
291 pwrdm_post_transition(NULL); 261 pwrdm_post_transition(NULL);
292 262
@@ -300,8 +270,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
300 */ 270 */
301int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) 271int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
302{ 272{
303 unsigned int cpu_state = 0;
304 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); 273 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
274 unsigned int cpu_state = 0;
305 275
306 if (omap_rev() == OMAP4430_REV_ES1_0) 276 if (omap_rev() == OMAP4430_REV_ES1_0)
307 return -ENXIO; 277 return -ENXIO;
@@ -309,8 +279,8 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
309 if (power_state == PWRDM_POWER_OFF) 279 if (power_state == PWRDM_POWER_OFF)
310 cpu_state = 1; 280 cpu_state = 1;
311 281
312 clear_cpu_prev_pwrst(cpu); 282 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
313 set_cpu_next_pwrst(cpu, power_state); 283 pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
314 set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); 284 set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
315 scu_pwrst_prepare(cpu, power_state); 285 scu_pwrst_prepare(cpu, power_state);
316 286
@@ -321,7 +291,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
321 */ 291 */
322 omap4_finish_suspend(cpu_state); 292 omap4_finish_suspend(cpu_state);
323 293
324 set_cpu_next_pwrst(cpu, PWRDM_POWER_ON); 294 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
325 return 0; 295 return 0;
326} 296}
327 297
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 361677983af0..d9727218dd0a 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -215,7 +215,7 @@ static void __init omap4_smp_init_cpus(void)
215 * Currently we can't call ioremap here because 215 * Currently we can't call ioremap here because
216 * SoC detection won't work until after init_early. 216 * SoC detection won't work until after init_early.
217 */ 217 */
218 scu_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_SCU_BASE); 218 scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base());
219 BUG_ON(!scu_base); 219 BUG_ON(!scu_base);
220 ncores = scu_get_core_count(scu_base); 220 ncores = scu_get_core_count(scu_base);
221 } else if (cpu_id == CPU_CORTEX_A15) { 221 } else if (cpu_id == CPU_CORTEX_A15) {
diff --git a/arch/arm/mach-omap2/omap44xx.h b/arch/arm/mach-omap2/omap44xx.h
index 43b927b2e2e8..8a515bb74639 100644
--- a/arch/arm/mach-omap2/omap44xx.h
+++ b/arch/arm/mach-omap2/omap44xx.h
@@ -40,7 +40,6 @@
40#define OMAP44XX_GIC_DIST_BASE 0x48241000 40#define OMAP44XX_GIC_DIST_BASE 0x48241000
41#define OMAP44XX_GIC_CPU_BASE 0x48240100 41#define OMAP44XX_GIC_CPU_BASE 0x48240100
42#define OMAP44XX_IRQ_GIC_START 32 42#define OMAP44XX_IRQ_GIC_START 32
43#define OMAP44XX_SCU_BASE 0x48240000
44#define OMAP44XX_LOCAL_TWD_BASE 0x48240600 43#define OMAP44XX_LOCAL_TWD_BASE 0x48240600
45#define OMAP44XX_L2CACHE_BASE 0x48242000 44#define OMAP44XX_L2CACHE_BASE 0x48242000
46#define OMAP44XX_WKUPGEN_BASE 0x48281000 45#define OMAP44XX_WKUPGEN_BASE 0x48281000
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index d109f06785da..381be7ac0c17 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -17,68 +17,15 @@
17 * to control power management and interconnect properties of their 17 * to control power management and interconnect properties of their
18 * devices. 18 * devices.
19 * 19 *
20 * In the medium- to long-term, this code should either be 20 * In the medium- to long-term, this code should be implemented as a
21 * a) implemented via arch-specific pointers in platform_data 21 * proper omap_bus/omap_device in Linux, no more platform_data func
22 * or 22 * pointers
23 * b) implemented as a proper omap_bus/omap_device in Linux, no more
24 * platform_data func pointers
25 * 23 *
26 * 24 *
27 * Guidelines for usage by driver authors:
28 *
29 * 1. These functions are intended to be used by device drivers via
30 * function pointers in struct platform_data. As an example,
31 * omap_device_enable() should be passed to the driver as
32 *
33 * struct foo_driver_platform_data {
34 * ...
35 * int (*device_enable)(struct platform_device *pdev);
36 * ...
37 * }
38 *
39 * Note that the generic "device_enable" name is used, rather than
40 * "omap_device_enable". This is so other architectures can pass in their
41 * own enable/disable functions here.
42 *
43 * This should be populated during device setup:
44 *
45 * ...
46 * pdata->device_enable = omap_device_enable;
47 * ...
48 *
49 * 2. Drivers should first check to ensure the function pointer is not null
50 * before calling it, as in:
51 *
52 * if (pdata->device_enable)
53 * pdata->device_enable(pdev);
54 *
55 * This allows other architectures that don't use similar device_enable()/
56 * device_shutdown() functions to execute normally.
57 *
58 * ...
59 *
60 * Suggested usage by device drivers:
61 *
62 * During device initialization:
63 * device_enable()
64 *
65 * During device idle:
66 * (save remaining device context if necessary)
67 * device_idle();
68 *
69 * During device resume:
70 * device_enable();
71 * (restore context if necessary)
72 *
73 * During device shutdown:
74 * device_shutdown()
75 * (device must be reinitialized at this point to use it again)
76 *
77 */ 25 */
78#undef DEBUG 26#undef DEBUG
79 27
80#include <linux/kernel.h> 28#include <linux/kernel.h>
81#include <linux/export.h>
82#include <linux/platform_device.h> 29#include <linux/platform_device.h>
83#include <linux/slab.h> 30#include <linux/slab.h>
84#include <linux/err.h> 31#include <linux/err.h>
@@ -93,155 +40,8 @@
93#include "omap_device.h" 40#include "omap_device.h"
94#include "omap_hwmod.h" 41#include "omap_hwmod.h"
95 42
96/* These parameters are passed to _omap_device_{de,}activate() */
97#define USE_WAKEUP_LAT 0
98#define IGNORE_WAKEUP_LAT 1
99
100static int omap_early_device_register(struct platform_device *pdev);
101
102static struct omap_device_pm_latency omap_default_latency[] = {
103 {
104 .deactivate_func = omap_device_idle_hwmods,
105 .activate_func = omap_device_enable_hwmods,
106 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
107 }
108};
109
110/* Private functions */ 43/* Private functions */
111 44
112/**
113 * _omap_device_activate - increase device readiness
114 * @od: struct omap_device *
115 * @ignore_lat: increase to latency target (0) or full readiness (1)?
116 *
117 * Increase readiness of omap_device @od (thus decreasing device
118 * wakeup latency, but consuming more power). If @ignore_lat is
119 * IGNORE_WAKEUP_LAT, make the omap_device fully active. Otherwise,
120 * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
121 * latency is greater than the requested maximum wakeup latency, step
122 * backwards in the omap_device_pm_latency table to ensure the
123 * device's maximum wakeup latency is less than or equal to the
124 * requested maximum wakeup latency. Returns 0.
125 */
126static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
127{
128 struct timespec a, b, c;
129
130 dev_dbg(&od->pdev->dev, "omap_device: activating\n");
131
132 while (od->pm_lat_level > 0) {
133 struct omap_device_pm_latency *odpl;
134 unsigned long long act_lat = 0;
135
136 od->pm_lat_level--;
137
138 odpl = od->pm_lats + od->pm_lat_level;
139
140 if (!ignore_lat &&
141 (od->dev_wakeup_lat <= od->_dev_wakeup_lat_limit))
142 break;
143
144 read_persistent_clock(&a);
145
146 /* XXX check return code */
147 odpl->activate_func(od);
148
149 read_persistent_clock(&b);
150
151 c = timespec_sub(b, a);
152 act_lat = timespec_to_ns(&c);
153
154 dev_dbg(&od->pdev->dev,
155 "omap_device: pm_lat %d: activate: elapsed time %llu nsec\n",
156 od->pm_lat_level, act_lat);
157
158 if (act_lat > odpl->activate_lat) {
159 odpl->activate_lat_worst = act_lat;
160 if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
161 odpl->activate_lat = act_lat;
162 dev_dbg(&od->pdev->dev,
163 "new worst case activate latency %d: %llu\n",
164 od->pm_lat_level, act_lat);
165 } else
166 dev_warn(&od->pdev->dev,
167 "activate latency %d higher than expected. (%llu > %d)\n",
168 od->pm_lat_level, act_lat,
169 odpl->activate_lat);
170 }
171
172 od->dev_wakeup_lat -= odpl->activate_lat;
173 }
174
175 return 0;
176}
177
178/**
179 * _omap_device_deactivate - decrease device readiness
180 * @od: struct omap_device *
181 * @ignore_lat: decrease to latency target (0) or full inactivity (1)?
182 *
183 * Decrease readiness of omap_device @od (thus increasing device
184 * wakeup latency, but conserving power). If @ignore_lat is
185 * IGNORE_WAKEUP_LAT, make the omap_device fully inactive. Otherwise,
186 * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
187 * latency is less than the requested maximum wakeup latency, step
188 * forwards in the omap_device_pm_latency table to ensure the device's
189 * maximum wakeup latency is less than or equal to the requested
190 * maximum wakeup latency. Returns 0.
191 */
192static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
193{
194 struct timespec a, b, c;
195
196 dev_dbg(&od->pdev->dev, "omap_device: deactivating\n");
197
198 while (od->pm_lat_level < od->pm_lats_cnt) {
199 struct omap_device_pm_latency *odpl;
200 unsigned long long deact_lat = 0;
201
202 odpl = od->pm_lats + od->pm_lat_level;
203
204 if (!ignore_lat &&
205 ((od->dev_wakeup_lat + odpl->activate_lat) >
206 od->_dev_wakeup_lat_limit))
207 break;
208
209 read_persistent_clock(&a);
210
211 /* XXX check return code */
212 odpl->deactivate_func(od);
213
214 read_persistent_clock(&b);
215
216 c = timespec_sub(b, a);
217 deact_lat = timespec_to_ns(&c);
218
219 dev_dbg(&od->pdev->dev,
220 "omap_device: pm_lat %d: deactivate: elapsed time %llu nsec\n",
221 od->pm_lat_level, deact_lat);
222
223 if (deact_lat > odpl->deactivate_lat) {
224 odpl->deactivate_lat_worst = deact_lat;
225 if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
226 odpl->deactivate_lat = deact_lat;
227 dev_dbg(&od->pdev->dev,
228 "new worst case deactivate latency %d: %llu\n",
229 od->pm_lat_level, deact_lat);
230 } else
231 dev_warn(&od->pdev->dev,
232 "deactivate latency %d higher than expected. (%llu > %d)\n",
233 od->pm_lat_level, deact_lat,
234 odpl->deactivate_lat);
235 }
236
237 od->dev_wakeup_lat += odpl->activate_lat;
238
239 od->pm_lat_level++;
240 }
241
242 return 0;
243}
244
245static void _add_clkdev(struct omap_device *od, const char *clk_alias, 45static void _add_clkdev(struct omap_device *od, const char *clk_alias,
246 const char *clk_name) 46 const char *clk_name)
247{ 47{
@@ -316,9 +116,6 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od,
316 * @oh: ptr to the single omap_hwmod that backs this omap_device 116 * @oh: ptr to the single omap_hwmod that backs this omap_device
317 * @pdata: platform_data ptr to associate with the platform_device 117 * @pdata: platform_data ptr to associate with the platform_device
318 * @pdata_len: amount of memory pointed to by @pdata 118 * @pdata_len: amount of memory pointed to by @pdata
319 * @pm_lats: pointer to a omap_device_pm_latency array for this device
320 * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
321 * @is_early_device: should the device be registered as an early device or not
322 * 119 *
323 * Function for building an omap_device already registered from device-tree 120 * Function for building an omap_device already registered from device-tree
324 * 121 *
@@ -357,7 +154,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
357 hwmods[i] = oh; 154 hwmods[i] = oh;
358 } 155 }
359 156
360 od = omap_device_alloc(pdev, hwmods, oh_cnt, NULL, 0); 157 od = omap_device_alloc(pdev, hwmods, oh_cnt);
361 if (!od) { 158 if (!od) {
362 dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", 159 dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",
363 oh_name); 160 oh_name);
@@ -408,6 +205,39 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
408 return NOTIFY_DONE; 205 return NOTIFY_DONE;
409} 206}
410 207
208/**
209 * _omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods
210 * @od: struct omap_device *od
211 *
212 * Enable all underlying hwmods. Returns 0.
213 */
214static int _omap_device_enable_hwmods(struct omap_device *od)
215{
216 int i;
217
218 for (i = 0; i < od->hwmods_cnt; i++)
219 omap_hwmod_enable(od->hwmods[i]);
220
221 /* XXX pass along return value here? */
222 return 0;
223}
224
225/**
226 * _omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods
227 * @od: struct omap_device *od
228 *
229 * Idle all underlying hwmods. Returns 0.
230 */
231static int _omap_device_idle_hwmods(struct omap_device *od)
232{
233 int i;
234
235 for (i = 0; i < od->hwmods_cnt; i++)
236 omap_hwmod_idle(od->hwmods[i]);
237
238 /* XXX pass along return value here? */
239 return 0;
240}
411 241
412/* Public functions for use by core code */ 242/* Public functions for use by core code */
413 243
@@ -527,18 +357,14 @@ static int _od_fill_dma_resources(struct omap_device *od,
527 * @oh: ptr to the single omap_hwmod that backs this omap_device 357 * @oh: ptr to the single omap_hwmod that backs this omap_device
528 * @pdata: platform_data ptr to associate with the platform_device 358 * @pdata: platform_data ptr to associate with the platform_device
529 * @pdata_len: amount of memory pointed to by @pdata 359 * @pdata_len: amount of memory pointed to by @pdata
530 * @pm_lats: pointer to a omap_device_pm_latency array for this device
531 * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
532 * 360 *
533 * Convenience function for allocating an omap_device structure and filling 361 * Convenience function for allocating an omap_device structure and filling
534 * hwmods, resources and pm_latency attributes. 362 * hwmods, and resources.
535 * 363 *
536 * Returns an struct omap_device pointer or ERR_PTR() on error; 364 * Returns an struct omap_device pointer or ERR_PTR() on error;
537 */ 365 */
538struct omap_device *omap_device_alloc(struct platform_device *pdev, 366struct omap_device *omap_device_alloc(struct platform_device *pdev,
539 struct omap_hwmod **ohs, int oh_cnt, 367 struct omap_hwmod **ohs, int oh_cnt)
540 struct omap_device_pm_latency *pm_lats,
541 int pm_lats_cnt)
542{ 368{
543 int ret = -ENOMEM; 369 int ret = -ENOMEM;
544 struct omap_device *od; 370 struct omap_device *od;
@@ -627,18 +453,6 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
627 goto oda_exit3; 453 goto oda_exit3;
628 454
629have_everything: 455have_everything:
630 if (!pm_lats) {
631 pm_lats = omap_default_latency;
632 pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
633 }
634
635 od->pm_lats_cnt = pm_lats_cnt;
636 od->pm_lats = kmemdup(pm_lats,
637 sizeof(struct omap_device_pm_latency) * pm_lats_cnt,
638 GFP_KERNEL);
639 if (!od->pm_lats)
640 goto oda_exit3;
641
642 pdev->archdata.od = od; 456 pdev->archdata.od = od;
643 457
644 for (i = 0; i < oh_cnt; i++) { 458 for (i = 0; i < oh_cnt; i++) {
@@ -664,7 +478,6 @@ void omap_device_delete(struct omap_device *od)
664 return; 478 return;
665 479
666 od->pdev->archdata.od = NULL; 480 od->pdev->archdata.od = NULL;
667 kfree(od->pm_lats);
668 kfree(od->hwmods); 481 kfree(od->hwmods);
669 kfree(od); 482 kfree(od);
670} 483}
@@ -676,9 +489,6 @@ void omap_device_delete(struct omap_device *od)
676 * @oh: ptr to the single omap_hwmod that backs this omap_device 489 * @oh: ptr to the single omap_hwmod that backs this omap_device
677 * @pdata: platform_data ptr to associate with the platform_device 490 * @pdata: platform_data ptr to associate with the platform_device
678 * @pdata_len: amount of memory pointed to by @pdata 491 * @pdata_len: amount of memory pointed to by @pdata
679 * @pm_lats: pointer to a omap_device_pm_latency array for this device
680 * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
681 * @is_early_device: should the device be registered as an early device or not
682 * 492 *
683 * Convenience function for building and registering a single 493 * Convenience function for building and registering a single
684 * omap_device record, which in turn builds and registers a 494 * omap_device record, which in turn builds and registers a
@@ -686,11 +496,10 @@ void omap_device_delete(struct omap_device *od)
686 * information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise, 496 * information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise,
687 * passes along the return value of omap_device_build_ss(). 497 * passes along the return value of omap_device_build_ss().
688 */ 498 */
689struct platform_device __init *omap_device_build(const char *pdev_name, int pdev_id, 499struct platform_device __init *omap_device_build(const char *pdev_name,
690 struct omap_hwmod *oh, void *pdata, 500 int pdev_id,
691 int pdata_len, 501 struct omap_hwmod *oh,
692 struct omap_device_pm_latency *pm_lats, 502 void *pdata, int pdata_len)
693 int pm_lats_cnt, int is_early_device)
694{ 503{
695 struct omap_hwmod *ohs[] = { oh }; 504 struct omap_hwmod *ohs[] = { oh };
696 505
@@ -698,8 +507,7 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev
698 return ERR_PTR(-EINVAL); 507 return ERR_PTR(-EINVAL);
699 508
700 return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata, 509 return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata,
701 pdata_len, pm_lats, pm_lats_cnt, 510 pdata_len);
702 is_early_device);
703} 511}
704 512
705/** 513/**
@@ -709,9 +517,6 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev
709 * @oh: ptr to the single omap_hwmod that backs this omap_device 517 * @oh: ptr to the single omap_hwmod that backs this omap_device
710 * @pdata: platform_data ptr to associate with the platform_device 518 * @pdata: platform_data ptr to associate with the platform_device
711 * @pdata_len: amount of memory pointed to by @pdata 519 * @pdata_len: amount of memory pointed to by @pdata
712 * @pm_lats: pointer to a omap_device_pm_latency array for this device
713 * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
714 * @is_early_device: should the device be registered as an early device or not
715 * 520 *
716 * Convenience function for building and registering an omap_device 521 * Convenience function for building and registering an omap_device
717 * subsystem record. Subsystem records consist of multiple 522 * subsystem record. Subsystem records consist of multiple
@@ -719,11 +524,11 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev
719 * platform_device record. Returns an ERR_PTR() on error, or passes 524 * platform_device record. Returns an ERR_PTR() on error, or passes
720 * along the return value of omap_device_register(). 525 * along the return value of omap_device_register().
721 */ 526 */
722struct platform_device __init *omap_device_build_ss(const char *pdev_name, int pdev_id, 527struct platform_device __init *omap_device_build_ss(const char *pdev_name,
723 struct omap_hwmod **ohs, int oh_cnt, 528 int pdev_id,
724 void *pdata, int pdata_len, 529 struct omap_hwmod **ohs,
725 struct omap_device_pm_latency *pm_lats, 530 int oh_cnt, void *pdata,
726 int pm_lats_cnt, int is_early_device) 531 int pdata_len)
727{ 532{
728 int ret = -ENOMEM; 533 int ret = -ENOMEM;
729 struct platform_device *pdev; 534 struct platform_device *pdev;
@@ -747,7 +552,7 @@ struct platform_device __init *omap_device_build_ss(const char *pdev_name, int p
747 else 552 else
748 dev_set_name(&pdev->dev, "%s", pdev->name); 553 dev_set_name(&pdev->dev, "%s", pdev->name);
749 554
750 od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt); 555 od = omap_device_alloc(pdev, ohs, oh_cnt);
751 if (IS_ERR(od)) 556 if (IS_ERR(od))
752 goto odbs_exit1; 557 goto odbs_exit1;
753 558
@@ -755,10 +560,7 @@ struct platform_device __init *omap_device_build_ss(const char *pdev_name, int p
755 if (ret) 560 if (ret)
756 goto odbs_exit2; 561 goto odbs_exit2;
757 562
758 if (is_early_device) 563 ret = omap_device_register(pdev);
759 ret = omap_early_device_register(pdev);
760 else
761 ret = omap_device_register(pdev);
762 if (ret) 564 if (ret)
763 goto odbs_exit2; 565 goto odbs_exit2;
764 566
@@ -775,24 +577,6 @@ odbs_exit:
775 return ERR_PTR(ret); 577 return ERR_PTR(ret);
776} 578}
777 579
778/**
779 * omap_early_device_register - register an omap_device as an early platform
780 * device.
781 * @od: struct omap_device * to register
782 *
783 * Register the omap_device structure. This currently just calls
784 * platform_early_add_device() on the underlying platform_device.
785 * Returns 0 by default.
786 */
787static int __init omap_early_device_register(struct platform_device *pdev)
788{
789 struct platform_device *devices[1];
790
791 devices[0] = pdev;
792 early_platform_add_devices(devices, 1);
793 return 0;
794}
795
796#ifdef CONFIG_PM_RUNTIME 580#ifdef CONFIG_PM_RUNTIME
797static int _od_runtime_suspend(struct device *dev) 581static int _od_runtime_suspend(struct device *dev)
798{ 582{
@@ -903,10 +687,9 @@ int omap_device_register(struct platform_device *pdev)
903 * to be accessible and ready to operate. This generally involves 687 * to be accessible and ready to operate. This generally involves
904 * enabling clocks, setting SYSCONFIG registers; and in the future may 688 * enabling clocks, setting SYSCONFIG registers; and in the future may
905 * involve remuxing pins. Device drivers should call this function 689 * involve remuxing pins. Device drivers should call this function
906 * (through platform_data function pointers) where they would normally 690 * indirectly via pm_runtime_get*(). Returns -EINVAL if called when
907 * enable clocks, etc. Returns -EINVAL if called when the omap_device 691 * the omap_device is already enabled, or passes along the return
908 * is already enabled, or passes along the return value of 692 * value of _omap_device_enable_hwmods().
909 * _omap_device_activate().
910 */ 693 */
911int omap_device_enable(struct platform_device *pdev) 694int omap_device_enable(struct platform_device *pdev)
912{ 695{
@@ -922,14 +705,8 @@ int omap_device_enable(struct platform_device *pdev)
922 return -EINVAL; 705 return -EINVAL;
923 } 706 }
924 707
925 /* Enable everything if we're enabling this device from scratch */ 708 ret = _omap_device_enable_hwmods(od);
926 if (od->_state == OMAP_DEVICE_STATE_UNKNOWN)
927 od->pm_lat_level = od->pm_lats_cnt;
928
929 ret = _omap_device_activate(od, IGNORE_WAKEUP_LAT);
930 709
931 od->dev_wakeup_lat = 0;
932 od->_dev_wakeup_lat_limit = UINT_MAX;
933 od->_state = OMAP_DEVICE_STATE_ENABLED; 710 od->_state = OMAP_DEVICE_STATE_ENABLED;
934 711
935 return ret; 712 return ret;
@@ -939,14 +716,10 @@ int omap_device_enable(struct platform_device *pdev)
939 * omap_device_idle - idle an omap_device 716 * omap_device_idle - idle an omap_device
940 * @od: struct omap_device * to idle 717 * @od: struct omap_device * to idle
941 * 718 *
942 * Idle omap_device @od by calling as many .deactivate_func() entries 719 * Idle omap_device @od. Device drivers call this function indirectly
943 * in the omap_device's pm_lats table as is possible without exceeding 720 * via pm_runtime_put*(). Returns -EINVAL if the omap_device is not
944 * the device's maximum wakeup latency limit, pm_lat_limit. Device
945 * drivers should call this function (through platform_data function
946 * pointers) where they would normally disable clocks after operations
947 * complete, etc.. Returns -EINVAL if the omap_device is not
948 * currently enabled, or passes along the return value of 721 * currently enabled, or passes along the return value of
949 * _omap_device_deactivate(). 722 * _omap_device_idle_hwmods().
950 */ 723 */
951int omap_device_idle(struct platform_device *pdev) 724int omap_device_idle(struct platform_device *pdev)
952{ 725{
@@ -962,7 +735,7 @@ int omap_device_idle(struct platform_device *pdev)
962 return -EINVAL; 735 return -EINVAL;
963 } 736 }
964 737
965 ret = _omap_device_deactivate(od, USE_WAKEUP_LAT); 738 ret = _omap_device_idle_hwmods(od);
966 739
967 od->_state = OMAP_DEVICE_STATE_IDLE; 740 od->_state = OMAP_DEVICE_STATE_IDLE;
968 741
@@ -970,42 +743,6 @@ int omap_device_idle(struct platform_device *pdev)
970} 743}
971 744
972/** 745/**
973 * omap_device_shutdown - shut down an omap_device
974 * @od: struct omap_device * to shut down
975 *
976 * Shut down omap_device @od by calling all .deactivate_func() entries
977 * in the omap_device's pm_lats table and then shutting down all of
978 * the underlying omap_hwmods. Used when a device is being "removed"
979 * or a device driver is being unloaded. Returns -EINVAL if the
980 * omap_device is not currently enabled or idle, or passes along the
981 * return value of _omap_device_deactivate().
982 */
983int omap_device_shutdown(struct platform_device *pdev)
984{
985 int ret, i;
986 struct omap_device *od;
987
988 od = to_omap_device(pdev);
989
990 if (od->_state != OMAP_DEVICE_STATE_ENABLED &&
991 od->_state != OMAP_DEVICE_STATE_IDLE) {
992 dev_warn(&pdev->dev,
993 "omap_device: %s() called from invalid state %d\n",
994 __func__, od->_state);
995 return -EINVAL;
996 }
997
998 ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT);
999
1000 for (i = 0; i < od->hwmods_cnt; i++)
1001 omap_hwmod_shutdown(od->hwmods[i]);
1002
1003 od->_state = OMAP_DEVICE_STATE_SHUTDOWN;
1004
1005 return ret;
1006}
1007
1008/**
1009 * omap_device_assert_hardreset - set a device's hardreset line 746 * omap_device_assert_hardreset - set a device's hardreset line
1010 * @pdev: struct platform_device * to reset 747 * @pdev: struct platform_device * to reset
1011 * @name: const char * name of the reset line 748 * @name: const char * name of the reset line
@@ -1061,86 +798,6 @@ int omap_device_deassert_hardreset(struct platform_device *pdev,
1061} 798}
1062 799
1063/** 800/**
1064 * omap_device_align_pm_lat - activate/deactivate device to match wakeup lat lim
1065 * @od: struct omap_device *
1066 *
1067 * When a device's maximum wakeup latency limit changes, call some of
1068 * the .activate_func or .deactivate_func function pointers in the
1069 * omap_device's pm_lats array to ensure that the device's maximum
1070 * wakeup latency is less than or equal to the new latency limit.
1071 * Intended to be called by OMAP PM code whenever a device's maximum
1072 * wakeup latency limit changes (e.g., via
1073 * omap_pm_set_dev_wakeup_lat()). Returns 0 if nothing needs to be
1074 * done (e.g., if the omap_device is not currently idle, or if the
1075 * wakeup latency is already current with the new limit) or passes
1076 * along the return value of _omap_device_deactivate() or
1077 * _omap_device_activate().
1078 */
1079int omap_device_align_pm_lat(struct platform_device *pdev,
1080 u32 new_wakeup_lat_limit)
1081{
1082 int ret = -EINVAL;
1083 struct omap_device *od;
1084
1085 od = to_omap_device(pdev);
1086
1087 if (new_wakeup_lat_limit == od->dev_wakeup_lat)
1088 return 0;
1089
1090 od->_dev_wakeup_lat_limit = new_wakeup_lat_limit;
1091
1092 if (od->_state != OMAP_DEVICE_STATE_IDLE)
1093 return 0;
1094 else if (new_wakeup_lat_limit > od->dev_wakeup_lat)
1095 ret = _omap_device_deactivate(od, USE_WAKEUP_LAT);
1096 else if (new_wakeup_lat_limit < od->dev_wakeup_lat)
1097 ret = _omap_device_activate(od, USE_WAKEUP_LAT);
1098
1099 return ret;
1100}
1101
1102/**
1103 * omap_device_get_pwrdm - return the powerdomain * associated with @od
1104 * @od: struct omap_device *
1105 *
1106 * Return the powerdomain associated with the first underlying
1107 * omap_hwmod for this omap_device. Intended for use by core OMAP PM
1108 * code. Returns NULL on error or a struct powerdomain * upon
1109 * success.
1110 */
1111struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
1112{
1113 /*
1114 * XXX Assumes that all omap_hwmod powerdomains are identical.
1115 * This may not necessarily be true. There should be a sanity
1116 * check in here to WARN() if any difference appears.
1117 */
1118 if (!od->hwmods_cnt)
1119 return NULL;
1120
1121 return omap_hwmod_get_pwrdm(od->hwmods[0]);
1122}
1123
1124/**
1125 * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base
1126 * @od: struct omap_device *
1127 *
1128 * Return the MPU's virtual address for the base of the hwmod, from
1129 * the ioremap() that the hwmod code does. Only valid if there is one
1130 * hwmod associated with this device. Returns NULL if there are zero
1131 * or more than one hwmods associated with this omap_device;
1132 * otherwise, passes along the return value from
1133 * omap_hwmod_get_mpu_rt_va().
1134 */
1135void __iomem *omap_device_get_rt_va(struct omap_device *od)
1136{
1137 if (od->hwmods_cnt != 1)
1138 return NULL;
1139
1140 return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
1141}
1142
1143/**
1144 * omap_device_get_by_hwmod_name() - convert a hwmod name to 801 * omap_device_get_by_hwmod_name() - convert a hwmod name to
1145 * device pointer. 802 * device pointer.
1146 * @oh_name: name of the hwmod device 803 * @oh_name: name of the hwmod device
@@ -1174,82 +831,6 @@ struct device *omap_device_get_by_hwmod_name(const char *oh_name)
1174 831
1175 return &oh->od->pdev->dev; 832 return &oh->od->pdev->dev;
1176} 833}
1177EXPORT_SYMBOL(omap_device_get_by_hwmod_name);
1178
1179/*
1180 * Public functions intended for use in omap_device_pm_latency
1181 * .activate_func and .deactivate_func function pointers
1182 */
1183
1184/**
1185 * omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods
1186 * @od: struct omap_device *od
1187 *
1188 * Enable all underlying hwmods. Returns 0.
1189 */
1190int omap_device_enable_hwmods(struct omap_device *od)
1191{
1192 int i;
1193
1194 for (i = 0; i < od->hwmods_cnt; i++)
1195 omap_hwmod_enable(od->hwmods[i]);
1196
1197 /* XXX pass along return value here? */
1198 return 0;
1199}
1200
1201/**
1202 * omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods
1203 * @od: struct omap_device *od
1204 *
1205 * Idle all underlying hwmods. Returns 0.
1206 */
1207int omap_device_idle_hwmods(struct omap_device *od)
1208{
1209 int i;
1210
1211 for (i = 0; i < od->hwmods_cnt; i++)
1212 omap_hwmod_idle(od->hwmods[i]);
1213
1214 /* XXX pass along return value here? */
1215 return 0;
1216}
1217
1218/**
1219 * omap_device_disable_clocks - disable all main and interface clocks
1220 * @od: struct omap_device *od
1221 *
1222 * Disable the main functional clock and interface clock for all of the
1223 * omap_hwmods associated with the omap_device. Returns 0.
1224 */
1225int omap_device_disable_clocks(struct omap_device *od)
1226{
1227 int i;
1228
1229 for (i = 0; i < od->hwmods_cnt; i++)
1230 omap_hwmod_disable_clocks(od->hwmods[i]);
1231
1232 /* XXX pass along return value here? */
1233 return 0;
1234}
1235
1236/**
1237 * omap_device_enable_clocks - enable all main and interface clocks
1238 * @od: struct omap_device *od
1239 *
1240 * Enable the main functional clock and interface clock for all of the
1241 * omap_hwmods associated with the omap_device. Returns 0.
1242 */
1243int omap_device_enable_clocks(struct omap_device *od)
1244{
1245 int i;
1246
1247 for (i = 0; i < od->hwmods_cnt; i++)
1248 omap_hwmod_enable_clocks(od->hwmods[i]);
1249
1250 /* XXX pass along return value here? */
1251 return 0;
1252}
1253 834
1254static struct notifier_block platform_nb = { 835static struct notifier_block platform_nb = {
1255 .notifier_call = _omap_device_notifier_call, 836 .notifier_call = _omap_device_notifier_call,
diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h
index 0933c599bf89..044c31d50e5b 100644
--- a/arch/arm/mach-omap2/omap_device.h
+++ b/arch/arm/mach-omap2/omap_device.h
@@ -13,20 +13,12 @@
13 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
15 * 15 *
16 * Eventually this type of functionality should either be 16 * This type of functionality should be implemented as a proper
17 * a) implemented via arch-specific pointers in platform_device 17 * omap_bus/omap_device in Linux.
18 * or
19 * b) implemented as a proper omap_bus/omap_device in Linux, no more
20 * platform_device
21 * 18 *
22 * omap_device differs from omap_hwmod in that it includes external 19 * omap_device differs from omap_hwmod in that it includes external
23 * (e.g., board- and system-level) integration details. omap_hwmod 20 * (e.g., board- and system-level) integration details. omap_hwmod
24 * stores hardware data that is invariant for a given OMAP chip. 21 * stores hardware data that is invariant for a given OMAP chip.
25 *
26 * To do:
27 * - GPIO integration
28 * - regulator integration
29 *
30 */ 22 */
31#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H 23#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
32#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H 24#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
@@ -45,19 +37,14 @@ extern struct dev_pm_domain omap_device_pm_domain;
45#define OMAP_DEVICE_STATE_SHUTDOWN 3 37#define OMAP_DEVICE_STATE_SHUTDOWN 3
46 38
47/* omap_device.flags values */ 39/* omap_device.flags values */
48#define OMAP_DEVICE_SUSPENDED BIT(0) 40#define OMAP_DEVICE_SUSPENDED BIT(0)
49#define OMAP_DEVICE_NO_IDLE_ON_SUSPEND BIT(1) 41#define OMAP_DEVICE_NO_IDLE_ON_SUSPEND BIT(1)
50 42
51/** 43/**
52 * struct omap_device - omap_device wrapper for platform_devices 44 * struct omap_device - omap_device wrapper for platform_devices
53 * @pdev: platform_device 45 * @pdev: platform_device
54 * @hwmods: (one .. many per omap_device) 46 * @hwmods: (one .. many per omap_device)
55 * @hwmods_cnt: ARRAY_SIZE() of @hwmods 47 * @hwmods_cnt: ARRAY_SIZE() of @hwmods
56 * @pm_lats: ptr to an omap_device_pm_latency table
57 * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
58 * @pm_lat_level: array index of the last odpl entry executed - -1 if never
59 * @dev_wakeup_lat: dev wakeup latency in nanoseconds
60 * @_dev_wakeup_lat_limit: dev wakeup latency limit in nsec - set by OMAP PM
61 * @_state: one of OMAP_DEVICE_STATE_* (see above) 48 * @_state: one of OMAP_DEVICE_STATE_* (see above)
62 * @flags: device flags 49 * @flags: device flags
63 * @_driver_status: one of BUS_NOTIFY_*_DRIVER from <linux/device.h> 50 * @_driver_status: one of BUS_NOTIFY_*_DRIVER from <linux/device.h>
@@ -71,12 +58,7 @@ extern struct dev_pm_domain omap_device_pm_domain;
71struct omap_device { 58struct omap_device {
72 struct platform_device *pdev; 59 struct platform_device *pdev;
73 struct omap_hwmod **hwmods; 60 struct omap_hwmod **hwmods;
74 struct omap_device_pm_latency *pm_lats;
75 u32 dev_wakeup_lat;
76 u32 _dev_wakeup_lat_limit;
77 unsigned long _driver_status; 61 unsigned long _driver_status;
78 u8 pm_lats_cnt;
79 s8 pm_lat_level;
80 u8 hwmods_cnt; 62 u8 hwmods_cnt;
81 u8 _state; 63 u8 _state;
82 u8 flags; 64 u8 flags;
@@ -86,36 +68,25 @@ struct omap_device {
86 68
87int omap_device_enable(struct platform_device *pdev); 69int omap_device_enable(struct platform_device *pdev);
88int omap_device_idle(struct platform_device *pdev); 70int omap_device_idle(struct platform_device *pdev);
89int omap_device_shutdown(struct platform_device *pdev);
90 71
91/* Core code interface */ 72/* Core code interface */
92 73
93struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, 74struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
94 struct omap_hwmod *oh, void *pdata, 75 struct omap_hwmod *oh, void *pdata,
95 int pdata_len, 76 int pdata_len);
96 struct omap_device_pm_latency *pm_lats,
97 int pm_lats_cnt, int is_early_device);
98 77
99struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, 78struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
100 struct omap_hwmod **oh, int oh_cnt, 79 struct omap_hwmod **oh, int oh_cnt,
101 void *pdata, int pdata_len, 80 void *pdata, int pdata_len);
102 struct omap_device_pm_latency *pm_lats,
103 int pm_lats_cnt, int is_early_device);
104 81
105struct omap_device *omap_device_alloc(struct platform_device *pdev, 82struct omap_device *omap_device_alloc(struct platform_device *pdev,
106 struct omap_hwmod **ohs, int oh_cnt, 83 struct omap_hwmod **ohs, int oh_cnt);
107 struct omap_device_pm_latency *pm_lats,
108 int pm_lats_cnt);
109void omap_device_delete(struct omap_device *od); 84void omap_device_delete(struct omap_device *od);
110int omap_device_register(struct platform_device *pdev); 85int omap_device_register(struct platform_device *pdev);
111 86
112void __iomem *omap_device_get_rt_va(struct omap_device *od);
113struct device *omap_device_get_by_hwmod_name(const char *oh_name); 87struct device *omap_device_get_by_hwmod_name(const char *oh_name);
114 88
115/* OMAP PM interface */ 89/* OMAP PM interface */
116int omap_device_align_pm_lat(struct platform_device *pdev,
117 u32 new_wakeup_lat_limit);
118struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
119int omap_device_get_context_loss_count(struct platform_device *pdev); 90int omap_device_get_context_loss_count(struct platform_device *pdev);
120 91
121/* Other */ 92/* Other */
@@ -124,40 +95,6 @@ int omap_device_assert_hardreset(struct platform_device *pdev,
124 const char *name); 95 const char *name);
125int omap_device_deassert_hardreset(struct platform_device *pdev, 96int omap_device_deassert_hardreset(struct platform_device *pdev,
126 const char *name); 97 const char *name);
127int omap_device_idle_hwmods(struct omap_device *od);
128int omap_device_enable_hwmods(struct omap_device *od);
129
130int omap_device_disable_clocks(struct omap_device *od);
131int omap_device_enable_clocks(struct omap_device *od);
132
133/*
134 * Entries should be kept in latency order ascending
135 *
136 * deact_lat is the maximum number of microseconds required to complete
137 * deactivate_func() at the device's slowest OPP.
138 *
139 * act_lat is the maximum number of microseconds required to complete
140 * activate_func() at the device's slowest OPP.
141 *
142 * This will result in some suboptimal power management decisions at fast
143 * OPPs, but avoids having to recompute all device power management decisions
144 * if the system shifts from a fast OPP to a slow OPP (in order to meet
145 * latency requirements).
146 *
147 * XXX should deactivate_func/activate_func() take platform_device pointers
148 * rather than omap_device pointers?
149 */
150struct omap_device_pm_latency {
151 u32 deactivate_lat;
152 u32 deactivate_lat_worst;
153 int (*deactivate_func)(struct omap_device *od);
154 u32 activate_lat;
155 u32 activate_lat_worst;
156 int (*activate_func)(struct omap_device *od);
157 u32 flags;
158};
159
160#define OMAP_DEVICE_LATENCY_AUTO_ADJUST BIT(1)
161 98
162/* Get omap_device pointer from platform_device pointer */ 99/* Get omap_device pointer from platform_device pointer */
163static inline struct omap_device *to_omap_device(struct platform_device *pdev) 100static inline struct omap_device *to_omap_device(struct platform_device *pdev)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6e70707cbb34..a8984989dec8 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -139,6 +139,8 @@
139#include <linux/slab.h> 139#include <linux/slab.h>
140#include <linux/bootmem.h> 140#include <linux/bootmem.h>
141 141
142#include <asm/system_misc.h>
143
142#include "clock.h" 144#include "clock.h"
143#include "omap_hwmod.h" 145#include "omap_hwmod.h"
144 146
@@ -2134,6 +2136,8 @@ static int _enable(struct omap_hwmod *oh)
2134 _enable_clocks(oh); 2136 _enable_clocks(oh);
2135 if (soc_ops.enable_module) 2137 if (soc_ops.enable_module)
2136 soc_ops.enable_module(oh); 2138 soc_ops.enable_module(oh);
2139 if (oh->flags & HWMOD_BLOCK_WFI)
2140 disable_hlt();
2137 2141
2138 if (soc_ops.update_context_lost) 2142 if (soc_ops.update_context_lost)
2139 soc_ops.update_context_lost(oh); 2143 soc_ops.update_context_lost(oh);
@@ -2195,6 +2199,8 @@ static int _idle(struct omap_hwmod *oh)
2195 _idle_sysc(oh); 2199 _idle_sysc(oh);
2196 _del_initiator_dep(oh, mpu_oh); 2200 _del_initiator_dep(oh, mpu_oh);
2197 2201
2202 if (oh->flags & HWMOD_BLOCK_WFI)
2203 enable_hlt();
2198 if (soc_ops.disable_module) 2204 if (soc_ops.disable_module)
2199 soc_ops.disable_module(oh); 2205 soc_ops.disable_module(oh);
2200 2206
@@ -2303,6 +2309,8 @@ static int _shutdown(struct omap_hwmod *oh)
2303 if (oh->_state == _HWMOD_STATE_ENABLED) { 2309 if (oh->_state == _HWMOD_STATE_ENABLED) {
2304 _del_initiator_dep(oh, mpu_oh); 2310 _del_initiator_dep(oh, mpu_oh);
2305 /* XXX what about the other system initiators here? dma, dsp */ 2311 /* XXX what about the other system initiators here? dma, dsp */
2312 if (oh->flags & HWMOD_BLOCK_WFI)
2313 enable_hlt();
2306 if (soc_ops.disable_module) 2314 if (soc_ops.disable_module)
2307 soc_ops.disable_module(oh); 2315 soc_ops.disable_module(oh);
2308 _disable_clocks(oh); 2316 _disable_clocks(oh);
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 3ae852a522f9..80c00e706d69 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -451,6 +451,14 @@ struct omap_hwmod_omap4_prcm {
451 * enabled. This prevents the hwmod code from being able to 451 * enabled. This prevents the hwmod code from being able to
452 * enable and reset the IP block early. XXX Eventually it should 452 * enable and reset the IP block early. XXX Eventually it should
453 * be possible to query the clock framework for this information. 453 * be possible to query the clock framework for this information.
454 * HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work
455 * correctly if the MPU is allowed to go idle while the
456 * peripherals are active. This is apparently true for the I2C on
457 * OMAP2420, and also the EMAC on AM3517/3505. It's unlikely that
458 * this is really true -- we're probably not configuring something
459 * correctly, or this is being abused to deal with some PM latency
460 * issues -- but we're currently suffering from a shortage of
461 * folks who are able to track these issues down properly.
454 */ 462 */
455#define HWMOD_SWSUP_SIDLE (1 << 0) 463#define HWMOD_SWSUP_SIDLE (1 << 0)
456#define HWMOD_SWSUP_MSTANDBY (1 << 1) 464#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -462,6 +470,7 @@ struct omap_hwmod_omap4_prcm {
462#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) 470#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
463#define HWMOD_16BIT_REG (1 << 8) 471#define HWMOD_16BIT_REG (1 << 8)
464#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) 472#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
473#define HWMOD_BLOCK_WFI (1 << 10)
465 474
466/* 475/*
467 * omap_hwmod._int_flags definitions 476 * omap_hwmod._int_flags definitions
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index b5efe58c0be0..6a764af6c6d3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -121,7 +121,12 @@ static struct omap_hwmod omap2420_i2c1_hwmod = {
121 }, 121 },
122 .class = &i2c_class, 122 .class = &i2c_class,
123 .dev_attr = &i2c_dev_attr, 123 .dev_attr = &i2c_dev_attr,
124 .flags = HWMOD_16BIT_REG, 124 /*
125 * From mach-omap2/pm24xx.c: "Putting MPU into the WFI state
126 * while a transfer is active seems to cause the I2C block to
127 * timeout. Why? Good question."
128 */
129 .flags = (HWMOD_16BIT_REG | HWMOD_BLOCK_WFI),
125}; 130};
126 131
127/* I2C2 */ 132/* I2C2 */
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 624a7e84a685..7ec1083ff604 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -616,7 +616,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = {
616 .clkdm_name = "abe_clkdm", 616 .clkdm_name = "abe_clkdm",
617 .mpu_irqs = omap44xx_dmic_irqs, 617 .mpu_irqs = omap44xx_dmic_irqs,
618 .sdma_reqs = omap44xx_dmic_sdma_reqs, 618 .sdma_reqs = omap44xx_dmic_sdma_reqs,
619 .main_clk = "dmic_fck", 619 .main_clk = "func_dmic_abe_gfclk",
620 .prcm = { 620 .prcm = {
621 .omap4 = { 621 .omap4 = {
622 .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET, 622 .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET,
@@ -1161,7 +1161,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
1161 .class = &omap44xx_gpio_hwmod_class, 1161 .class = &omap44xx_gpio_hwmod_class,
1162 .clkdm_name = "l4_wkup_clkdm", 1162 .clkdm_name = "l4_wkup_clkdm",
1163 .mpu_irqs = omap44xx_gpio1_irqs, 1163 .mpu_irqs = omap44xx_gpio1_irqs,
1164 .main_clk = "gpio1_ick", 1164 .main_clk = "l4_wkup_clk_mux_ck",
1165 .prcm = { 1165 .prcm = {
1166 .omap4 = { 1166 .omap4 = {
1167 .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET, 1167 .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET,
@@ -1190,7 +1190,7 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
1190 .clkdm_name = "l4_per_clkdm", 1190 .clkdm_name = "l4_per_clkdm",
1191 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, 1191 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1192 .mpu_irqs = omap44xx_gpio2_irqs, 1192 .mpu_irqs = omap44xx_gpio2_irqs,
1193 .main_clk = "gpio2_ick", 1193 .main_clk = "l4_div_ck",
1194 .prcm = { 1194 .prcm = {
1195 .omap4 = { 1195 .omap4 = {
1196 .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET, 1196 .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET,
@@ -1219,7 +1219,7 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
1219 .clkdm_name = "l4_per_clkdm", 1219 .clkdm_name = "l4_per_clkdm",
1220 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, 1220 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1221 .mpu_irqs = omap44xx_gpio3_irqs, 1221 .mpu_irqs = omap44xx_gpio3_irqs,
1222 .main_clk = "gpio3_ick", 1222 .main_clk = "l4_div_ck",
1223 .prcm = { 1223 .prcm = {
1224 .omap4 = { 1224 .omap4 = {
1225 .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET, 1225 .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET,
@@ -1248,7 +1248,7 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
1248 .clkdm_name = "l4_per_clkdm", 1248 .clkdm_name = "l4_per_clkdm",
1249 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, 1249 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1250 .mpu_irqs = omap44xx_gpio4_irqs, 1250 .mpu_irqs = omap44xx_gpio4_irqs,
1251 .main_clk = "gpio4_ick", 1251 .main_clk = "l4_div_ck",
1252 .prcm = { 1252 .prcm = {
1253 .omap4 = { 1253 .omap4 = {
1254 .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET, 1254 .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET,
@@ -1277,7 +1277,7 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
1277 .clkdm_name = "l4_per_clkdm", 1277 .clkdm_name = "l4_per_clkdm",
1278 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, 1278 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1279 .mpu_irqs = omap44xx_gpio5_irqs, 1279 .mpu_irqs = omap44xx_gpio5_irqs,
1280 .main_clk = "gpio5_ick", 1280 .main_clk = "l4_div_ck",
1281 .prcm = { 1281 .prcm = {
1282 .omap4 = { 1282 .omap4 = {
1283 .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET, 1283 .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET,
@@ -1306,7 +1306,7 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
1306 .clkdm_name = "l4_per_clkdm", 1306 .clkdm_name = "l4_per_clkdm",
1307 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, 1307 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1308 .mpu_irqs = omap44xx_gpio6_irqs, 1308 .mpu_irqs = omap44xx_gpio6_irqs,
1309 .main_clk = "gpio6_ick", 1309 .main_clk = "l4_div_ck",
1310 .prcm = { 1310 .prcm = {
1311 .omap4 = { 1311 .omap4 = {
1312 .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET, 1312 .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET,
@@ -1405,7 +1405,7 @@ static struct omap_hwmod omap44xx_gpu_hwmod = {
1405 .class = &omap44xx_gpu_hwmod_class, 1405 .class = &omap44xx_gpu_hwmod_class,
1406 .clkdm_name = "l3_gfx_clkdm", 1406 .clkdm_name = "l3_gfx_clkdm",
1407 .mpu_irqs = omap44xx_gpu_irqs, 1407 .mpu_irqs = omap44xx_gpu_irqs,
1408 .main_clk = "gpu_fck", 1408 .main_clk = "sgx_clk_mux",
1409 .prcm = { 1409 .prcm = {
1410 .omap4 = { 1410 .omap4 = {
1411 .clkctrl_offs = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET, 1411 .clkctrl_offs = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET,
@@ -1446,7 +1446,7 @@ static struct omap_hwmod omap44xx_hdq1w_hwmod = {
1446 .clkdm_name = "l4_per_clkdm", 1446 .clkdm_name = "l4_per_clkdm",
1447 .flags = HWMOD_INIT_NO_RESET, /* XXX temporary */ 1447 .flags = HWMOD_INIT_NO_RESET, /* XXX temporary */
1448 .mpu_irqs = omap44xx_hdq1w_irqs, 1448 .mpu_irqs = omap44xx_hdq1w_irqs,
1449 .main_clk = "hdq1w_fck", 1449 .main_clk = "func_12m_fclk",
1450 .prcm = { 1450 .prcm = {
1451 .omap4 = { 1451 .omap4 = {
1452 .clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET, 1452 .clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET,
@@ -1550,7 +1550,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {
1550 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, 1550 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
1551 .mpu_irqs = omap44xx_i2c1_irqs, 1551 .mpu_irqs = omap44xx_i2c1_irqs,
1552 .sdma_reqs = omap44xx_i2c1_sdma_reqs, 1552 .sdma_reqs = omap44xx_i2c1_sdma_reqs,
1553 .main_clk = "i2c1_fck", 1553 .main_clk = "func_96m_fclk",
1554 .prcm = { 1554 .prcm = {
1555 .omap4 = { 1555 .omap4 = {
1556 .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET, 1556 .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET,
@@ -1580,7 +1580,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {
1580 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, 1580 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
1581 .mpu_irqs = omap44xx_i2c2_irqs, 1581 .mpu_irqs = omap44xx_i2c2_irqs,
1582 .sdma_reqs = omap44xx_i2c2_sdma_reqs, 1582 .sdma_reqs = omap44xx_i2c2_sdma_reqs,
1583 .main_clk = "i2c2_fck", 1583 .main_clk = "func_96m_fclk",
1584 .prcm = { 1584 .prcm = {
1585 .omap4 = { 1585 .omap4 = {
1586 .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET, 1586 .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET,
@@ -1610,7 +1610,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {
1610 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, 1610 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
1611 .mpu_irqs = omap44xx_i2c3_irqs, 1611 .mpu_irqs = omap44xx_i2c3_irqs,
1612 .sdma_reqs = omap44xx_i2c3_sdma_reqs, 1612 .sdma_reqs = omap44xx_i2c3_sdma_reqs,
1613 .main_clk = "i2c3_fck", 1613 .main_clk = "func_96m_fclk",
1614 .prcm = { 1614 .prcm = {
1615 .omap4 = { 1615 .omap4 = {
1616 .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET, 1616 .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET,
@@ -1640,7 +1640,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {
1640 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, 1640 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
1641 .mpu_irqs = omap44xx_i2c4_irqs, 1641 .mpu_irqs = omap44xx_i2c4_irqs,
1642 .sdma_reqs = omap44xx_i2c4_sdma_reqs, 1642 .sdma_reqs = omap44xx_i2c4_sdma_reqs,
1643 .main_clk = "i2c4_fck", 1643 .main_clk = "func_96m_fclk",
1644 .prcm = { 1644 .prcm = {
1645 .omap4 = { 1645 .omap4 = {
1646 .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET, 1646 .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET,
@@ -1743,7 +1743,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = {
1743 .clkdm_name = "iss_clkdm", 1743 .clkdm_name = "iss_clkdm",
1744 .mpu_irqs = omap44xx_iss_irqs, 1744 .mpu_irqs = omap44xx_iss_irqs,
1745 .sdma_reqs = omap44xx_iss_sdma_reqs, 1745 .sdma_reqs = omap44xx_iss_sdma_reqs,
1746 .main_clk = "iss_fck", 1746 .main_clk = "ducati_clk_mux_ck",
1747 .prcm = { 1747 .prcm = {
1748 .omap4 = { 1748 .omap4 = {
1749 .clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET, 1749 .clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET,
@@ -1785,7 +1785,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = {
1785 .mpu_irqs = omap44xx_iva_irqs, 1785 .mpu_irqs = omap44xx_iva_irqs,
1786 .rst_lines = omap44xx_iva_resets, 1786 .rst_lines = omap44xx_iva_resets,
1787 .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), 1787 .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets),
1788 .main_clk = "iva_fck", 1788 .main_clk = "dpll_iva_m5x2_ck",
1789 .prcm = { 1789 .prcm = {
1790 .omap4 = { 1790 .omap4 = {
1791 .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET, 1791 .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET,
@@ -1829,7 +1829,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = {
1829 .class = &omap44xx_kbd_hwmod_class, 1829 .class = &omap44xx_kbd_hwmod_class,
1830 .clkdm_name = "l4_wkup_clkdm", 1830 .clkdm_name = "l4_wkup_clkdm",
1831 .mpu_irqs = omap44xx_kbd_irqs, 1831 .mpu_irqs = omap44xx_kbd_irqs,
1832 .main_clk = "kbd_fck", 1832 .main_clk = "sys_32k_ck",
1833 .prcm = { 1833 .prcm = {
1834 .omap4 = { 1834 .omap4 = {
1835 .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET, 1835 .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET,
@@ -1920,7 +1920,7 @@ static struct omap_hwmod omap44xx_mcasp_hwmod = {
1920 .clkdm_name = "abe_clkdm", 1920 .clkdm_name = "abe_clkdm",
1921 .mpu_irqs = omap44xx_mcasp_irqs, 1921 .mpu_irqs = omap44xx_mcasp_irqs,
1922 .sdma_reqs = omap44xx_mcasp_sdma_reqs, 1922 .sdma_reqs = omap44xx_mcasp_sdma_reqs,
1923 .main_clk = "mcasp_fck", 1923 .main_clk = "func_mcasp_abe_gfclk",
1924 .prcm = { 1924 .prcm = {
1925 .omap4 = { 1925 .omap4 = {
1926 .clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET, 1926 .clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET,
@@ -1972,7 +1972,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
1972 .clkdm_name = "abe_clkdm", 1972 .clkdm_name = "abe_clkdm",
1973 .mpu_irqs = omap44xx_mcbsp1_irqs, 1973 .mpu_irqs = omap44xx_mcbsp1_irqs,
1974 .sdma_reqs = omap44xx_mcbsp1_sdma_reqs, 1974 .sdma_reqs = omap44xx_mcbsp1_sdma_reqs,
1975 .main_clk = "mcbsp1_fck", 1975 .main_clk = "func_mcbsp1_gfclk",
1976 .prcm = { 1976 .prcm = {
1977 .omap4 = { 1977 .omap4 = {
1978 .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET, 1978 .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET,
@@ -2007,7 +2007,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
2007 .clkdm_name = "abe_clkdm", 2007 .clkdm_name = "abe_clkdm",
2008 .mpu_irqs = omap44xx_mcbsp2_irqs, 2008 .mpu_irqs = omap44xx_mcbsp2_irqs,
2009 .sdma_reqs = omap44xx_mcbsp2_sdma_reqs, 2009 .sdma_reqs = omap44xx_mcbsp2_sdma_reqs,
2010 .main_clk = "mcbsp2_fck", 2010 .main_clk = "func_mcbsp2_gfclk",
2011 .prcm = { 2011 .prcm = {
2012 .omap4 = { 2012 .omap4 = {
2013 .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET, 2013 .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET,
@@ -2042,7 +2042,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
2042 .clkdm_name = "abe_clkdm", 2042 .clkdm_name = "abe_clkdm",
2043 .mpu_irqs = omap44xx_mcbsp3_irqs, 2043 .mpu_irqs = omap44xx_mcbsp3_irqs,
2044 .sdma_reqs = omap44xx_mcbsp3_sdma_reqs, 2044 .sdma_reqs = omap44xx_mcbsp3_sdma_reqs,
2045 .main_clk = "mcbsp3_fck", 2045 .main_clk = "func_mcbsp3_gfclk",
2046 .prcm = { 2046 .prcm = {
2047 .omap4 = { 2047 .omap4 = {
2048 .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET, 2048 .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET,
@@ -2077,7 +2077,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
2077 .clkdm_name = "l4_per_clkdm", 2077 .clkdm_name = "l4_per_clkdm",
2078 .mpu_irqs = omap44xx_mcbsp4_irqs, 2078 .mpu_irqs = omap44xx_mcbsp4_irqs,
2079 .sdma_reqs = omap44xx_mcbsp4_sdma_reqs, 2079 .sdma_reqs = omap44xx_mcbsp4_sdma_reqs,
2080 .main_clk = "mcbsp4_fck", 2080 .main_clk = "per_mcbsp4_gfclk",
2081 .prcm = { 2081 .prcm = {
2082 .omap4 = { 2082 .omap4 = {
2083 .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET, 2083 .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET,
@@ -2140,7 +2140,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
2140 .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE, 2140 .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE,
2141 .mpu_irqs = omap44xx_mcpdm_irqs, 2141 .mpu_irqs = omap44xx_mcpdm_irqs,
2142 .sdma_reqs = omap44xx_mcpdm_sdma_reqs, 2142 .sdma_reqs = omap44xx_mcpdm_sdma_reqs,
2143 .main_clk = "mcpdm_fck", 2143 .main_clk = "pad_clks_ck",
2144 .prcm = { 2144 .prcm = {
2145 .omap4 = { 2145 .omap4 = {
2146 .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET, 2146 .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET,
@@ -2201,7 +2201,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = {
2201 .clkdm_name = "l4_per_clkdm", 2201 .clkdm_name = "l4_per_clkdm",
2202 .mpu_irqs = omap44xx_mcspi1_irqs, 2202 .mpu_irqs = omap44xx_mcspi1_irqs,
2203 .sdma_reqs = omap44xx_mcspi1_sdma_reqs, 2203 .sdma_reqs = omap44xx_mcspi1_sdma_reqs,
2204 .main_clk = "mcspi1_fck", 2204 .main_clk = "func_48m_fclk",
2205 .prcm = { 2205 .prcm = {
2206 .omap4 = { 2206 .omap4 = {
2207 .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, 2207 .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
@@ -2237,7 +2237,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = {
2237 .clkdm_name = "l4_per_clkdm", 2237 .clkdm_name = "l4_per_clkdm",
2238 .mpu_irqs = omap44xx_mcspi2_irqs, 2238 .mpu_irqs = omap44xx_mcspi2_irqs,
2239 .sdma_reqs = omap44xx_mcspi2_sdma_reqs, 2239 .sdma_reqs = omap44xx_mcspi2_sdma_reqs,
2240 .main_clk = "mcspi2_fck", 2240 .main_clk = "func_48m_fclk",
2241 .prcm = { 2241 .prcm = {
2242 .omap4 = { 2242 .omap4 = {
2243 .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, 2243 .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
@@ -2273,7 +2273,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = {
2273 .clkdm_name = "l4_per_clkdm", 2273 .clkdm_name = "l4_per_clkdm",
2274 .mpu_irqs = omap44xx_mcspi3_irqs, 2274 .mpu_irqs = omap44xx_mcspi3_irqs,
2275 .sdma_reqs = omap44xx_mcspi3_sdma_reqs, 2275 .sdma_reqs = omap44xx_mcspi3_sdma_reqs,
2276 .main_clk = "mcspi3_fck", 2276 .main_clk = "func_48m_fclk",
2277 .prcm = { 2277 .prcm = {
2278 .omap4 = { 2278 .omap4 = {
2279 .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, 2279 .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
@@ -2307,7 +2307,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = {
2307 .clkdm_name = "l4_per_clkdm", 2307 .clkdm_name = "l4_per_clkdm",
2308 .mpu_irqs = omap44xx_mcspi4_irqs, 2308 .mpu_irqs = omap44xx_mcspi4_irqs,
2309 .sdma_reqs = omap44xx_mcspi4_sdma_reqs, 2309 .sdma_reqs = omap44xx_mcspi4_sdma_reqs,
2310 .main_clk = "mcspi4_fck", 2310 .main_clk = "func_48m_fclk",
2311 .prcm = { 2311 .prcm = {
2312 .omap4 = { 2312 .omap4 = {
2313 .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, 2313 .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
@@ -2363,7 +2363,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = {
2363 .clkdm_name = "l3_init_clkdm", 2363 .clkdm_name = "l3_init_clkdm",
2364 .mpu_irqs = omap44xx_mmc1_irqs, 2364 .mpu_irqs = omap44xx_mmc1_irqs,
2365 .sdma_reqs = omap44xx_mmc1_sdma_reqs, 2365 .sdma_reqs = omap44xx_mmc1_sdma_reqs,
2366 .main_clk = "mmc1_fck", 2366 .main_clk = "hsmmc1_fclk",
2367 .prcm = { 2367 .prcm = {
2368 .omap4 = { 2368 .omap4 = {
2369 .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET, 2369 .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET,
@@ -2392,7 +2392,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = {
2392 .clkdm_name = "l3_init_clkdm", 2392 .clkdm_name = "l3_init_clkdm",
2393 .mpu_irqs = omap44xx_mmc2_irqs, 2393 .mpu_irqs = omap44xx_mmc2_irqs,
2394 .sdma_reqs = omap44xx_mmc2_sdma_reqs, 2394 .sdma_reqs = omap44xx_mmc2_sdma_reqs,
2395 .main_clk = "mmc2_fck", 2395 .main_clk = "hsmmc2_fclk",
2396 .prcm = { 2396 .prcm = {
2397 .omap4 = { 2397 .omap4 = {
2398 .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET, 2398 .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET,
@@ -2420,7 +2420,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = {
2420 .clkdm_name = "l4_per_clkdm", 2420 .clkdm_name = "l4_per_clkdm",
2421 .mpu_irqs = omap44xx_mmc3_irqs, 2421 .mpu_irqs = omap44xx_mmc3_irqs,
2422 .sdma_reqs = omap44xx_mmc3_sdma_reqs, 2422 .sdma_reqs = omap44xx_mmc3_sdma_reqs,
2423 .main_clk = "mmc3_fck", 2423 .main_clk = "func_48m_fclk",
2424 .prcm = { 2424 .prcm = {
2425 .omap4 = { 2425 .omap4 = {
2426 .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET, 2426 .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET,
@@ -2448,7 +2448,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = {
2448 .clkdm_name = "l4_per_clkdm", 2448 .clkdm_name = "l4_per_clkdm",
2449 .mpu_irqs = omap44xx_mmc4_irqs, 2449 .mpu_irqs = omap44xx_mmc4_irqs,
2450 .sdma_reqs = omap44xx_mmc4_sdma_reqs, 2450 .sdma_reqs = omap44xx_mmc4_sdma_reqs,
2451 .main_clk = "mmc4_fck", 2451 .main_clk = "func_48m_fclk",
2452 .prcm = { 2452 .prcm = {
2453 .omap4 = { 2453 .omap4 = {
2454 .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET, 2454 .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET,
@@ -2476,7 +2476,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = {
2476 .clkdm_name = "l4_per_clkdm", 2476 .clkdm_name = "l4_per_clkdm",
2477 .mpu_irqs = omap44xx_mmc5_irqs, 2477 .mpu_irqs = omap44xx_mmc5_irqs,
2478 .sdma_reqs = omap44xx_mmc5_sdma_reqs, 2478 .sdma_reqs = omap44xx_mmc5_sdma_reqs,
2479 .main_clk = "mmc5_fck", 2479 .main_clk = "func_48m_fclk",
2480 .prcm = { 2480 .prcm = {
2481 .omap4 = { 2481 .omap4 = {
2482 .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET, 2482 .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET,
@@ -2718,7 +2718,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
2718 .name = "ocp2scp_usb_phy", 2718 .name = "ocp2scp_usb_phy",
2719 .class = &omap44xx_ocp2scp_hwmod_class, 2719 .class = &omap44xx_ocp2scp_hwmod_class,
2720 .clkdm_name = "l3_init_clkdm", 2720 .clkdm_name = "l3_init_clkdm",
2721 .main_clk = "ocp2scp_usb_phy_phy_48m", 2721 .main_clk = "func_48m_fclk",
2722 .prcm = { 2722 .prcm = {
2723 .omap4 = { 2723 .omap4 = {
2724 .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, 2724 .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET,
@@ -3155,7 +3155,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
3155 .clkdm_name = "l4_wkup_clkdm", 3155 .clkdm_name = "l4_wkup_clkdm",
3156 .flags = HWMOD_SET_DEFAULT_CLOCKACT, 3156 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
3157 .mpu_irqs = omap44xx_timer1_irqs, 3157 .mpu_irqs = omap44xx_timer1_irqs,
3158 .main_clk = "timer1_fck", 3158 .main_clk = "dmt1_clk_mux",
3159 .prcm = { 3159 .prcm = {
3160 .omap4 = { 3160 .omap4 = {
3161 .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET, 3161 .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET,
@@ -3178,7 +3178,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
3178 .clkdm_name = "l4_per_clkdm", 3178 .clkdm_name = "l4_per_clkdm",
3179 .flags = HWMOD_SET_DEFAULT_CLOCKACT, 3179 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
3180 .mpu_irqs = omap44xx_timer2_irqs, 3180 .mpu_irqs = omap44xx_timer2_irqs,
3181 .main_clk = "timer2_fck", 3181 .main_clk = "cm2_dm2_mux",
3182 .prcm = { 3182 .prcm = {
3183 .omap4 = { 3183 .omap4 = {
3184 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET, 3184 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET,
@@ -3199,7 +3199,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {
3199 .class = &omap44xx_timer_hwmod_class, 3199 .class = &omap44xx_timer_hwmod_class,
3200 .clkdm_name = "l4_per_clkdm", 3200 .clkdm_name = "l4_per_clkdm",
3201 .mpu_irqs = omap44xx_timer3_irqs, 3201 .mpu_irqs = omap44xx_timer3_irqs,
3202 .main_clk = "timer3_fck", 3202 .main_clk = "cm2_dm3_mux",
3203 .prcm = { 3203 .prcm = {
3204 .omap4 = { 3204 .omap4 = {
3205 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET, 3205 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET,
@@ -3220,7 +3220,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {
3220 .class = &omap44xx_timer_hwmod_class, 3220 .class = &omap44xx_timer_hwmod_class,
3221 .clkdm_name = "l4_per_clkdm", 3221 .clkdm_name = "l4_per_clkdm",
3222 .mpu_irqs = omap44xx_timer4_irqs, 3222 .mpu_irqs = omap44xx_timer4_irqs,
3223 .main_clk = "timer4_fck", 3223 .main_clk = "cm2_dm4_mux",
3224 .prcm = { 3224 .prcm = {
3225 .omap4 = { 3225 .omap4 = {
3226 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET, 3226 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET,
@@ -3241,7 +3241,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
3241 .class = &omap44xx_timer_hwmod_class, 3241 .class = &omap44xx_timer_hwmod_class,
3242 .clkdm_name = "abe_clkdm", 3242 .clkdm_name = "abe_clkdm",
3243 .mpu_irqs = omap44xx_timer5_irqs, 3243 .mpu_irqs = omap44xx_timer5_irqs,
3244 .main_clk = "timer5_fck", 3244 .main_clk = "timer5_sync_mux",
3245 .prcm = { 3245 .prcm = {
3246 .omap4 = { 3246 .omap4 = {
3247 .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET, 3247 .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET,
@@ -3263,8 +3263,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
3263 .class = &omap44xx_timer_hwmod_class, 3263 .class = &omap44xx_timer_hwmod_class,
3264 .clkdm_name = "abe_clkdm", 3264 .clkdm_name = "abe_clkdm",
3265 .mpu_irqs = omap44xx_timer6_irqs, 3265 .mpu_irqs = omap44xx_timer6_irqs,
3266 3266 .main_clk = "timer6_sync_mux",
3267 .main_clk = "timer6_fck",
3268 .prcm = { 3267 .prcm = {
3269 .omap4 = { 3268 .omap4 = {
3270 .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET, 3269 .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET,
@@ -3286,7 +3285,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
3286 .class = &omap44xx_timer_hwmod_class, 3285 .class = &omap44xx_timer_hwmod_class,
3287 .clkdm_name = "abe_clkdm", 3286 .clkdm_name = "abe_clkdm",
3288 .mpu_irqs = omap44xx_timer7_irqs, 3287 .mpu_irqs = omap44xx_timer7_irqs,
3289 .main_clk = "timer7_fck", 3288 .main_clk = "timer7_sync_mux",
3290 .prcm = { 3289 .prcm = {
3291 .omap4 = { 3290 .omap4 = {
3292 .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET, 3291 .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET,
@@ -3308,7 +3307,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {
3308 .class = &omap44xx_timer_hwmod_class, 3307 .class = &omap44xx_timer_hwmod_class,
3309 .clkdm_name = "abe_clkdm", 3308 .clkdm_name = "abe_clkdm",
3310 .mpu_irqs = omap44xx_timer8_irqs, 3309 .mpu_irqs = omap44xx_timer8_irqs,
3311 .main_clk = "timer8_fck", 3310 .main_clk = "timer8_sync_mux",
3312 .prcm = { 3311 .prcm = {
3313 .omap4 = { 3312 .omap4 = {
3314 .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET, 3313 .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET,
@@ -3330,7 +3329,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = {
3330 .class = &omap44xx_timer_hwmod_class, 3329 .class = &omap44xx_timer_hwmod_class,
3331 .clkdm_name = "l4_per_clkdm", 3330 .clkdm_name = "l4_per_clkdm",
3332 .mpu_irqs = omap44xx_timer9_irqs, 3331 .mpu_irqs = omap44xx_timer9_irqs,
3333 .main_clk = "timer9_fck", 3332 .main_clk = "cm2_dm9_mux",
3334 .prcm = { 3333 .prcm = {
3335 .omap4 = { 3334 .omap4 = {
3336 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET, 3335 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET,
@@ -3353,7 +3352,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
3353 .clkdm_name = "l4_per_clkdm", 3352 .clkdm_name = "l4_per_clkdm",
3354 .flags = HWMOD_SET_DEFAULT_CLOCKACT, 3353 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
3355 .mpu_irqs = omap44xx_timer10_irqs, 3354 .mpu_irqs = omap44xx_timer10_irqs,
3356 .main_clk = "timer10_fck", 3355 .main_clk = "cm2_dm10_mux",
3357 .prcm = { 3356 .prcm = {
3358 .omap4 = { 3357 .omap4 = {
3359 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET, 3358 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET,
@@ -3375,7 +3374,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = {
3375 .class = &omap44xx_timer_hwmod_class, 3374 .class = &omap44xx_timer_hwmod_class,
3376 .clkdm_name = "l4_per_clkdm", 3375 .clkdm_name = "l4_per_clkdm",
3377 .mpu_irqs = omap44xx_timer11_irqs, 3376 .mpu_irqs = omap44xx_timer11_irqs,
3378 .main_clk = "timer11_fck", 3377 .main_clk = "cm2_dm11_mux",
3379 .prcm = { 3378 .prcm = {
3380 .omap4 = { 3379 .omap4 = {
3381 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET, 3380 .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET,
@@ -3426,7 +3425,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {
3426 .clkdm_name = "l4_per_clkdm", 3425 .clkdm_name = "l4_per_clkdm",
3427 .mpu_irqs = omap44xx_uart1_irqs, 3426 .mpu_irqs = omap44xx_uart1_irqs,
3428 .sdma_reqs = omap44xx_uart1_sdma_reqs, 3427 .sdma_reqs = omap44xx_uart1_sdma_reqs,
3429 .main_clk = "uart1_fck", 3428 .main_clk = "func_48m_fclk",
3430 .prcm = { 3429 .prcm = {
3431 .omap4 = { 3430 .omap4 = {
3432 .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET, 3431 .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET,
@@ -3454,7 +3453,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {
3454 .clkdm_name = "l4_per_clkdm", 3453 .clkdm_name = "l4_per_clkdm",
3455 .mpu_irqs = omap44xx_uart2_irqs, 3454 .mpu_irqs = omap44xx_uart2_irqs,
3456 .sdma_reqs = omap44xx_uart2_sdma_reqs, 3455 .sdma_reqs = omap44xx_uart2_sdma_reqs,
3457 .main_clk = "uart2_fck", 3456 .main_clk = "func_48m_fclk",
3458 .prcm = { 3457 .prcm = {
3459 .omap4 = { 3458 .omap4 = {
3460 .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET, 3459 .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET,
@@ -3483,7 +3482,7 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
3483 .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, 3482 .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
3484 .mpu_irqs = omap44xx_uart3_irqs, 3483 .mpu_irqs = omap44xx_uart3_irqs,
3485 .sdma_reqs = omap44xx_uart3_sdma_reqs, 3484 .sdma_reqs = omap44xx_uart3_sdma_reqs,
3486 .main_clk = "uart3_fck", 3485 .main_clk = "func_48m_fclk",
3487 .prcm = { 3486 .prcm = {
3488 .omap4 = { 3487 .omap4 = {
3489 .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET, 3488 .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET,
@@ -3511,7 +3510,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
3511 .clkdm_name = "l4_per_clkdm", 3510 .clkdm_name = "l4_per_clkdm",
3512 .mpu_irqs = omap44xx_uart4_irqs, 3511 .mpu_irqs = omap44xx_uart4_irqs,
3513 .sdma_reqs = omap44xx_uart4_sdma_reqs, 3512 .sdma_reqs = omap44xx_uart4_sdma_reqs,
3514 .main_clk = "uart4_fck", 3513 .main_clk = "func_48m_fclk",
3515 .prcm = { 3514 .prcm = {
3516 .omap4 = { 3515 .omap4 = {
3517 .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET, 3516 .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET,
@@ -3790,7 +3789,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
3790 .class = &omap44xx_wd_timer_hwmod_class, 3789 .class = &omap44xx_wd_timer_hwmod_class,
3791 .clkdm_name = "l4_wkup_clkdm", 3790 .clkdm_name = "l4_wkup_clkdm",
3792 .mpu_irqs = omap44xx_wd_timer2_irqs, 3791 .mpu_irqs = omap44xx_wd_timer2_irqs,
3793 .main_clk = "wd_timer2_fck", 3792 .main_clk = "sys_32k_ck",
3794 .prcm = { 3793 .prcm = {
3795 .omap4 = { 3794 .omap4 = {
3796 .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET, 3795 .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET,
@@ -3811,7 +3810,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
3811 .class = &omap44xx_wd_timer_hwmod_class, 3810 .class = &omap44xx_wd_timer_hwmod_class,
3812 .clkdm_name = "abe_clkdm", 3811 .clkdm_name = "abe_clkdm",
3813 .mpu_irqs = omap44xx_wd_timer3_irqs, 3812 .mpu_irqs = omap44xx_wd_timer3_irqs,
3814 .main_clk = "wd_timer3_fck", 3813 .main_clk = "sys_32k_ck",
3815 .prcm = { 3814 .prcm = {
3816 .omap4 = { 3815 .omap4 = {
3817 .clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET, 3816 .clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET,
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index e0ac8a31d4e0..1edd000a8143 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -83,10 +83,8 @@ static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
83 strncmp(clkdm->name, "dpll", 4) == 0) 83 strncmp(clkdm->name, "dpll", 4) == 0)
84 return 0; 84 return 0;
85 85
86 seq_printf(s, "%s->%s (%d)", clkdm->name, 86 seq_printf(s, "%s->%s (%d)\n", clkdm->name, clkdm->pwrdm.ptr->name,
87 clkdm->pwrdm.ptr->name, 87 clkdm->usecount);
88 atomic_read(&clkdm->usecount));
89 seq_printf(s, "\n");
90 88
91 return 0; 89 return 0;
92} 90}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 9c65eddd97cc..cd6682df5625 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -32,8 +32,6 @@
32#include "pm.h" 32#include "pm.h"
33#include "twl-common.h" 33#include "twl-common.h"
34 34
35static struct omap_device_pm_latency *pm_lats;
36
37/* 35/*
38 * omap_pm_suspend: points to a function that does the SoC-specific 36 * omap_pm_suspend: points to a function that does the SoC-specific
39 * suspend work 37 * suspend work
@@ -82,7 +80,7 @@ static int __init _init_omap_device(char *name)
82 __func__, name)) 80 __func__, name))
83 return -ENODEV; 81 return -ENODEV;
84 82
85 pdev = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false); 83 pdev = omap_device_build(oh->name, 0, oh, NULL, 0);
86 if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n", 84 if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n",
87 __func__, name)) 85 __func__, name))
88 return -ENODEV; 86 return -ENODEV;
@@ -108,80 +106,19 @@ static void __init omap2_init_processor_devices(void)
108 } 106 }
109} 107}
110 108
111/* Types of sleep_switch used in omap_set_pwrdm_state */
112#define FORCEWAKEUP_SWITCH 0
113#define LOWPOWERSTATE_SWITCH 1
114
115int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) 109int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
116{ 110{
111 /* XXX The usecount test is racy */
117 if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) && 112 if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
118 !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) 113 !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
119 clkdm_allow_idle(clkdm); 114 clkdm_allow_idle(clkdm);
120 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && 115 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
121 atomic_read(&clkdm->usecount) == 0) 116 clkdm->usecount == 0)
122 clkdm_sleep(clkdm); 117 clkdm_sleep(clkdm);
123 return 0; 118 return 0;
124} 119}
125 120
126/* 121/*
127 * This sets pwrdm state (other than mpu & core. Currently only ON &
128 * RET are supported.
129 */
130int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
131{
132 u8 curr_pwrst, next_pwrst;
133 int sleep_switch = -1, ret = 0, hwsup = 0;
134
135 if (!pwrdm || IS_ERR(pwrdm))
136 return -EINVAL;
137
138 while (!(pwrdm->pwrsts & (1 << pwrst))) {
139 if (pwrst == PWRDM_POWER_OFF)
140 return ret;
141 pwrst--;
142 }
143
144 next_pwrst = pwrdm_read_next_pwrst(pwrdm);
145 if (next_pwrst == pwrst)
146 return ret;
147
148 curr_pwrst = pwrdm_read_pwrst(pwrdm);
149 if (curr_pwrst < PWRDM_POWER_ON) {
150 if ((curr_pwrst > pwrst) &&
151 (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
152 sleep_switch = LOWPOWERSTATE_SWITCH;
153 } else {
154 hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
155 clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
156 sleep_switch = FORCEWAKEUP_SWITCH;
157 }
158 }
159
160 ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
161 if (ret)
162 pr_err("%s: unable to set power state of powerdomain: %s\n",
163 __func__, pwrdm->name);
164
165 switch (sleep_switch) {
166 case FORCEWAKEUP_SWITCH:
167 if (hwsup)
168 clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
169 else
170 clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
171 break;
172 case LOWPOWERSTATE_SWITCH:
173 pwrdm_set_lowpwrstchange(pwrdm);
174 pwrdm_wait_transition(pwrdm);
175 pwrdm_state_switch(pwrdm);
176 break;
177 }
178
179 return ret;
180}
181
182
183
184/*
185 * This API is to be called during init to set the various voltage 122 * This API is to be called during init to set the various voltage
186 * domains to the voltage as per the opp table. Typically we boot up 123 * domains to the voltage as per the opp table. Typically we boot up
187 * at the nominal voltage. So this function finds out the rate of 124 * at the nominal voltage. So this function finds out the rate of
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index c22503b17abd..7bdd22afce69 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -33,7 +33,6 @@ static inline int omap4_idle_init(void)
33extern void *omap3_secure_ram_storage; 33extern void *omap3_secure_ram_storage;
34extern void omap3_pm_off_mode_enable(int); 34extern void omap3_pm_off_mode_enable(int);
35extern void omap_sram_idle(void); 35extern void omap_sram_idle(void);
36extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
37extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); 36extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);
38extern int (*omap_pm_suspend)(void); 37extern int (*omap_pm_suspend)(void);
39 38
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index c333fa6dffa8..b2a4df623545 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -90,11 +90,7 @@ static int omap2_enter_full_retention(void)
90 omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); 90 omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
91 omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); 91 omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
92 92
93 /* 93 pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);
94 * Set MPU powerdomain's next power state to RETENTION;
95 * preserve logic state during retention
96 */
97 pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
98 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); 94 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
99 95
100 /* Workaround to kill USB */ 96 /* Workaround to kill USB */
@@ -137,15 +133,10 @@ no_sleep:
137 /* Mask future PRCM-to-MPU interrupts */ 133 /* Mask future PRCM-to-MPU interrupts */
138 omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); 134 omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
139 135
140 return 0; 136 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
141} 137 pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON);
142
143static int omap2_i2c_active(void)
144{
145 u32 l;
146 138
147 l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); 139 return 0;
148 return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK);
149} 140}
150 141
151static int sti_console_enabled; 142static int sti_console_enabled;
@@ -172,11 +163,6 @@ static int omap2_allow_mpu_retention(void)
172 163
173static void omap2_enter_mpu_retention(void) 164static void omap2_enter_mpu_retention(void)
174{ 165{
175 /* Putting MPU into the WFI state while a transfer is active
176 * seems to cause the I2C block to timeout. Why? Good question. */
177 if (omap2_i2c_active())
178 return;
179
180 /* The peripherals seem not to be able to wake up the MPU when 166 /* The peripherals seem not to be able to wake up the MPU when
181 * it is in retention mode. */ 167 * it is in retention mode. */
182 if (omap2_allow_mpu_retention()) { 168 if (omap2_allow_mpu_retention()) {
@@ -186,17 +172,16 @@ static void omap2_enter_mpu_retention(void)
186 omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); 172 omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
187 173
188 /* Try to enter MPU retention */ 174 /* Try to enter MPU retention */
189 omap2_prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) | 175 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
190 OMAP_LOGICRETSTATE_MASK, 176
191 MPU_MOD, OMAP2_PM_PWSTCTRL);
192 } else { 177 } else {
193 /* Block MPU retention */ 178 /* Block MPU retention */
194 179 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
195 omap2_prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD,
196 OMAP2_PM_PWSTCTRL);
197 } 180 }
198 181
199 omap2_sram_idle(); 182 omap2_sram_idle();
183
184 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
200} 185}
201 186
202static int omap2_can_sleep(void) 187static int omap2_can_sleep(void)
@@ -251,25 +236,17 @@ static void __init prcm_setup_regs(void)
251 for (i = 0; i < num_mem_banks; i++) 236 for (i = 0; i < num_mem_banks; i++)
252 pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET); 237 pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);
253 238
254 /* Set CORE powerdomain's next power state to RETENTION */ 239 pwrdm_set_logic_retst(core_pwrdm, PWRDM_POWER_RET);
255 pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);
256 240
257 /*
258 * Set MPU powerdomain's next power state to RETENTION;
259 * preserve logic state during retention
260 */
261 pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); 241 pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
262 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
263 242
264 /* Force-power down DSP, GFX powerdomains */ 243 /* Force-power down DSP, GFX powerdomains */
265 244
266 pwrdm = clkdm_get_pwrdm(dsp_clkdm); 245 pwrdm = clkdm_get_pwrdm(dsp_clkdm);
267 pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); 246 pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
268 clkdm_sleep(dsp_clkdm);
269 247
270 pwrdm = clkdm_get_pwrdm(gfx_clkdm); 248 pwrdm = clkdm_get_pwrdm(gfx_clkdm);
271 pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); 249 pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
272 clkdm_sleep(gfx_clkdm);
273 250
274 /* Enable hardware-supervised idle for all clkdms */ 251 /* Enable hardware-supervised idle for all clkdms */
275 clkdm_for_each(omap_pm_clkdms_setup, NULL); 252 clkdm_for_each(omap_pm_clkdms_setup, NULL);
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 75052b3bc943..9debf822687c 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -48,8 +48,7 @@ static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])
48 } 48 }
49 } 49 }
50 50
51 omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0, 51 omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0);
52 NULL, 0, 0);
53 WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n", 52 WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
54 dev_name); 53 dev_name);
55 54
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index dea62a9aad07..8e61d80bf6b3 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -19,6 +19,7 @@
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/spinlock.h>
22#include <trace/events/power.h> 23#include <trace/events/power.h>
23 24
24#include "cm2xxx_3xxx.h" 25#include "cm2xxx_3xxx.h"
@@ -42,6 +43,16 @@ enum {
42 PWRDM_STATE_PREV, 43 PWRDM_STATE_PREV,
43}; 44};
44 45
46/*
47 * Types of sleep_switch used internally in omap_set_pwrdm_state()
48 * and its associated static functions
49 *
50 * XXX Better documentation is needed here
51 */
52#define ALREADYACTIVE_SWITCH 0
53#define FORCEWAKEUP_SWITCH 1
54#define LOWPOWERSTATE_SWITCH 2
55#define ERROR_SWITCH 3
45 56
46/* pwrdm_list contains all registered struct powerdomains */ 57/* pwrdm_list contains all registered struct powerdomains */
47static LIST_HEAD(pwrdm_list); 58static LIST_HEAD(pwrdm_list);
@@ -101,6 +112,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
101 pwrdm->voltdm.ptr = voltdm; 112 pwrdm->voltdm.ptr = voltdm;
102 INIT_LIST_HEAD(&pwrdm->voltdm_node); 113 INIT_LIST_HEAD(&pwrdm->voltdm_node);
103 voltdm_add_pwrdm(voltdm, pwrdm); 114 voltdm_add_pwrdm(voltdm, pwrdm);
115 spin_lock_init(&pwrdm->_lock);
104 116
105 list_add(&pwrdm->node, &pwrdm_list); 117 list_add(&pwrdm->node, &pwrdm_list);
106 118
@@ -112,7 +124,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
112 for (i = 0; i < pwrdm->banks; i++) 124 for (i = 0; i < pwrdm->banks; i++)
113 pwrdm->ret_mem_off_counter[i] = 0; 125 pwrdm->ret_mem_off_counter[i] = 0;
114 126
115 pwrdm_wait_transition(pwrdm); 127 arch_pwrdm->pwrdm_wait_transition(pwrdm);
116 pwrdm->state = pwrdm_read_pwrst(pwrdm); 128 pwrdm->state = pwrdm_read_pwrst(pwrdm);
117 pwrdm->state_counter[pwrdm->state] = 1; 129 pwrdm->state_counter[pwrdm->state] = 1;
118 130
@@ -143,7 +155,7 @@ static void _update_logic_membank_counters(struct powerdomain *pwrdm)
143static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) 155static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
144{ 156{
145 157
146 int prev, state, trace_state = 0; 158 int prev, next, state, trace_state = 0;
147 159
148 if (pwrdm == NULL) 160 if (pwrdm == NULL)
149 return -EINVAL; 161 return -EINVAL;
@@ -164,9 +176,10 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
164 * If the power domain did not hit the desired state, 176 * If the power domain did not hit the desired state,
165 * generate a trace event with both the desired and hit states 177 * generate a trace event with both the desired and hit states
166 */ 178 */
167 if (state != prev) { 179 next = pwrdm_read_next_pwrst(pwrdm);
180 if (next != prev) {
168 trace_state = (PWRDM_TRACE_STATES_FLAG | 181 trace_state = (PWRDM_TRACE_STATES_FLAG |
169 ((state & OMAP_POWERSTATE_MASK) << 8) | 182 ((next & OMAP_POWERSTATE_MASK) << 8) |
170 ((prev & OMAP_POWERSTATE_MASK) << 0)); 183 ((prev & OMAP_POWERSTATE_MASK) << 0));
171 trace_power_domain_target(pwrdm->name, trace_state, 184 trace_power_domain_target(pwrdm->name, trace_state,
172 smp_processor_id()); 185 smp_processor_id());
@@ -199,6 +212,80 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
199 return 0; 212 return 0;
200} 213}
201 214
215/**
216 * _pwrdm_save_clkdm_state_and_activate - prepare for power state change
217 * @pwrdm: struct powerdomain * to operate on
218 * @curr_pwrst: current power state of @pwrdm
219 * @pwrst: power state to switch to
220 * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised
221 *
222 * Determine whether the powerdomain needs to be turned on before
223 * attempting to switch power states. Called by
224 * omap_set_pwrdm_state(). NOTE that if the powerdomain contains
225 * multiple clockdomains, this code assumes that the first clockdomain
226 * supports software-supervised wakeup mode - potentially a problem.
227 * Returns the power state switch mode currently in use (see the
228 * "Types of sleep_switch" comment above).
229 */
230static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
231 u8 curr_pwrst, u8 pwrst,
232 bool *hwsup)
233{
234 u8 sleep_switch;
235
236 if (curr_pwrst < 0) {
237 WARN_ON(1);
238 sleep_switch = ERROR_SWITCH;
239 } else if (curr_pwrst < PWRDM_POWER_ON) {
240 if (curr_pwrst > pwrst &&
241 pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
242 arch_pwrdm->pwrdm_set_lowpwrstchange) {
243 sleep_switch = LOWPOWERSTATE_SWITCH;
244 } else {
245 *hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
246 clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]);
247 sleep_switch = FORCEWAKEUP_SWITCH;
248 }
249 } else {
250 sleep_switch = ALREADYACTIVE_SWITCH;
251 }
252
253 return sleep_switch;
254}
255
256/**
257 * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
258 * @pwrdm: struct powerdomain * to operate on
259 * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
260 * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode?
261 *
262 * Restore the clockdomain state perturbed by
263 * _pwrdm_save_clkdm_state_and_activate(), and call the power state
264 * bookkeeping code. Called by omap_set_pwrdm_state(). NOTE that if
265 * the powerdomain contains multiple clockdomains, this assumes that
266 * the first associated clockdomain supports either
267 * hardware-supervised idle control in the register, or
268 * software-supervised sleep. No return value.
269 */
270static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
271 u8 sleep_switch, bool hwsup)
272{
273 switch (sleep_switch) {
274 case FORCEWAKEUP_SWITCH:
275 if (hwsup)
276 clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
277 else
278 clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]);
279 break;
280 case LOWPOWERSTATE_SWITCH:
281 if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
282 arch_pwrdm->pwrdm_set_lowpwrstchange)
283 arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
284 pwrdm_state_switch_nolock(pwrdm);
285 break;
286 }
287}
288
202/* Public functions */ 289/* Public functions */
203 290
204/** 291/**
@@ -275,6 +362,30 @@ int pwrdm_complete_init(void)
275} 362}
276 363
277/** 364/**
365 * pwrdm_lock - acquire a Linux spinlock on a powerdomain
366 * @pwrdm: struct powerdomain * to lock
367 *
368 * Acquire the powerdomain spinlock on @pwrdm. No return value.
369 */
370void pwrdm_lock(struct powerdomain *pwrdm)
371 __acquires(&pwrdm->_lock)
372{
373 spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags);
374}
375
376/**
377 * pwrdm_unlock - release a Linux spinlock on a powerdomain
378 * @pwrdm: struct powerdomain * to unlock
379 *
380 * Release the powerdomain spinlock on @pwrdm. No return value.
381 */
382void pwrdm_unlock(struct powerdomain *pwrdm)
383 __releases(&pwrdm->_lock)
384{
385 spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags);
386}
387
388/**
278 * pwrdm_lookup - look up a powerdomain by name, return a pointer 389 * pwrdm_lookup - look up a powerdomain by name, return a pointer
279 * @name: name of powerdomain 390 * @name: name of powerdomain
280 * 391 *
@@ -920,65 +1031,27 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
920 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; 1031 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
921} 1032}
922 1033
923/** 1034int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
924 * pwrdm_set_lowpwrstchange - Request a low power state change
925 * @pwrdm: struct powerdomain *
926 *
927 * Allows a powerdomain to transtion to a lower power sleep state
928 * from an existing sleep state without waking up the powerdomain.
929 * Returns -EINVAL if the powerdomain pointer is null or if the
930 * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0
931 * upon success.
932 */
933int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
934{
935 int ret = -EINVAL;
936
937 if (!pwrdm)
938 return -EINVAL;
939
940 if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE))
941 return -EINVAL;
942
943 pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
944 pwrdm->name);
945
946 if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange)
947 ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
948
949 return ret;
950}
951
952/**
953 * pwrdm_wait_transition - wait for powerdomain power transition to finish
954 * @pwrdm: struct powerdomain * to wait for
955 *
956 * If the powerdomain @pwrdm is in the process of a state transition,
957 * spin until it completes the power transition, or until an iteration
958 * bailout value is reached. Returns -EINVAL if the powerdomain
959 * pointer is null, -EAGAIN if the bailout value was reached, or
960 * returns 0 upon success.
961 */
962int pwrdm_wait_transition(struct powerdomain *pwrdm)
963{ 1035{
964 int ret = -EINVAL; 1036 int ret;
965 1037
966 if (!pwrdm) 1038 if (!pwrdm || !arch_pwrdm)
967 return -EINVAL; 1039 return -EINVAL;
968 1040
969 if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition) 1041 ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
970 ret = arch_pwrdm->pwrdm_wait_transition(pwrdm); 1042 if (!ret)
1043 ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
971 1044
972 return ret; 1045 return ret;
973} 1046}
974 1047
975int pwrdm_state_switch(struct powerdomain *pwrdm) 1048int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
976{ 1049{
977 int ret; 1050 int ret;
978 1051
979 ret = pwrdm_wait_transition(pwrdm); 1052 pwrdm_lock(pwrdm);
980 if (!ret) 1053 ret = pwrdm_state_switch_nolock(pwrdm);
981 ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); 1054 pwrdm_unlock(pwrdm);
982 1055
983 return ret; 1056 return ret;
984} 1057}
@@ -1004,6 +1077,61 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)
1004} 1077}
1005 1078
1006/** 1079/**
1080 * omap_set_pwrdm_state - change a powerdomain's current power state
1081 * @pwrdm: struct powerdomain * to change the power state of
1082 * @pwrst: power state to change to
1083 *
1084 * Change the current hardware power state of the powerdomain
1085 * represented by @pwrdm to the power state represented by @pwrst.
1086 * Returns -EINVAL if @pwrdm is null or invalid or if the
1087 * powerdomain's current power state could not be read, or returns 0
1088 * upon success or if @pwrdm does not support @pwrst or any
1089 * lower-power state. XXX Should not return 0 if the @pwrdm does not
1090 * support @pwrst or any lower-power state: this should be an error.
1091 */
1092int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
1093{
1094 u8 curr_pwrst, next_pwrst, sleep_switch;
1095 int ret = 0;
1096 bool hwsup = false;
1097
1098 if (!pwrdm || IS_ERR(pwrdm))
1099 return -EINVAL;
1100
1101 while (!(pwrdm->pwrsts & (1 << pwrst))) {
1102 if (pwrst == PWRDM_POWER_OFF)
1103 return ret;
1104 pwrst--;
1105 }
1106
1107 pwrdm_lock(pwrdm);
1108
1109 curr_pwrst = pwrdm_read_pwrst(pwrdm);
1110 next_pwrst = pwrdm_read_next_pwrst(pwrdm);
1111 if (curr_pwrst == pwrst && next_pwrst == pwrst)
1112 goto osps_out;
1113
1114 sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst,
1115 pwrst, &hwsup);
1116 if (sleep_switch == ERROR_SWITCH) {
1117 ret = -EINVAL;
1118 goto osps_out;
1119 }
1120
1121 ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
1122 if (ret)
1123 pr_err("%s: unable to set power state of powerdomain: %s\n",
1124 __func__, pwrdm->name);
1125
1126 _pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup);
1127
1128osps_out:
1129 pwrdm_unlock(pwrdm);
1130
1131 return ret;
1132}
1133
1134/**
1007 * pwrdm_get_context_loss_count - get powerdomain's context loss count 1135 * pwrdm_get_context_loss_count - get powerdomain's context loss count
1008 * @pwrdm: struct powerdomain * to wait for 1136 * @pwrdm: struct powerdomain * to wait for
1009 * 1137 *
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 5277d56eb37f..140c36074fed 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -19,8 +19,7 @@
19 19
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/list.h> 21#include <linux/list.h>
22 22#include <linux/spinlock.h>
23#include <linux/atomic.h>
24 23
25#include "voltage.h" 24#include "voltage.h"
26 25
@@ -44,18 +43,20 @@
44#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON) 43#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON)
45 44
46 45
47/* Powerdomain flags */ 46/*
48#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */ 47 * Powerdomain flags (struct powerdomain.flags)
49#define PWRDM_HAS_MPU_QUIRK (1 << 1) /* MPU pwr domain has MEM bank 0 bits 48 *
50 * in MEM bank 1 position. This is 49 * PWRDM_HAS_HDWR_SAR - powerdomain has hardware save-and-restore support
51 * true for OMAP3430 50 *
52 */ 51 * PWRDM_HAS_MPU_QUIRK - MPU pwr domain has MEM bank 0 bits in MEM
53#define PWRDM_HAS_LOWPOWERSTATECHANGE (1 << 2) /* 52 * bank 1 position. This is true for OMAP3430
54 * support to transition from a 53 *
55 * sleep state to a lower sleep 54 * PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state
56 * state without waking up the 55 * to a lower sleep state without waking up the powerdomain
57 * powerdomain 56 */
58 */ 57#define PWRDM_HAS_HDWR_SAR BIT(0)
58#define PWRDM_HAS_MPU_QUIRK BIT(1)
59#define PWRDM_HAS_LOWPOWERSTATECHANGE BIT(2)
59 60
60/* 61/*
61 * Number of memory banks that are power-controllable. On OMAP4430, the 62 * Number of memory banks that are power-controllable. On OMAP4430, the
@@ -103,6 +104,8 @@ struct powerdomain;
103 * @state_counter: 104 * @state_counter:
104 * @timer: 105 * @timer:
105 * @state_timer: 106 * @state_timer:
107 * @_lock: spinlock used to serialize powerdomain and some clockdomain ops
108 * @_lock_flags: stored flags when @_lock is taken
106 * 109 *
107 * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h. 110 * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
108 */ 111 */
@@ -127,7 +130,8 @@ struct powerdomain {
127 unsigned state_counter[PWRDM_MAX_PWRSTS]; 130 unsigned state_counter[PWRDM_MAX_PWRSTS];
128 unsigned ret_logic_off_counter; 131 unsigned ret_logic_off_counter;
129 unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS]; 132 unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
130 133 spinlock_t _lock;
134 unsigned long _lock_flags;
131 const u8 pwrstctrl_offs; 135 const u8 pwrstctrl_offs;
132 const u8 pwrstst_offs; 136 const u8 pwrstst_offs;
133 const u32 logicretstate_mask; 137 const u32 logicretstate_mask;
@@ -162,6 +166,16 @@ struct powerdomain {
162 * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd 166 * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd
163 * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep 167 * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep
164 * @pwrdm_wait_transition: Wait for a pd state transition to complete 168 * @pwrdm_wait_transition: Wait for a pd state transition to complete
169 *
170 * Regarding @pwrdm_set_lowpwrstchange: On the OMAP2 and 3-family
171 * chips, a powerdomain's power state is not allowed to directly
172 * transition from one low-power state (e.g., CSWR) to another
173 * low-power state (e.g., OFF) without first waking up the
174 * powerdomain. This wastes energy. So OMAP4 chips support the
175 * ability to transition a powerdomain power state directly from one
176 * low-power state to another. The function pointed to by
177 * @pwrdm_set_lowpwrstchange is intended to configure the OMAP4
178 * hardware powerdomain state machine to enable this feature.
165 */ 179 */
166struct pwrdm_ops { 180struct pwrdm_ops {
167 int (*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst); 181 int (*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst);
@@ -225,15 +239,15 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
225int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm); 239int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
226bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); 240bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
227 241
228int pwrdm_wait_transition(struct powerdomain *pwrdm); 242int pwrdm_state_switch_nolock(struct powerdomain *pwrdm);
229
230int pwrdm_state_switch(struct powerdomain *pwrdm); 243int pwrdm_state_switch(struct powerdomain *pwrdm);
231int pwrdm_pre_transition(struct powerdomain *pwrdm); 244int pwrdm_pre_transition(struct powerdomain *pwrdm);
232int pwrdm_post_transition(struct powerdomain *pwrdm); 245int pwrdm_post_transition(struct powerdomain *pwrdm);
233int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
234int pwrdm_get_context_loss_count(struct powerdomain *pwrdm); 246int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
235bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); 247bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
236 248
249extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 state);
250
237extern void omap242x_powerdomains_init(void); 251extern void omap242x_powerdomains_init(void);
238extern void omap243x_powerdomains_init(void); 252extern void omap243x_powerdomains_init(void);
239extern void omap3xxx_powerdomains_init(void); 253extern void omap3xxx_powerdomains_init(void);
@@ -253,5 +267,7 @@ extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);
253extern struct powerdomain wkup_omap2_pwrdm; 267extern struct powerdomain wkup_omap2_pwrdm;
254extern struct powerdomain gfx_omap2_pwrdm; 268extern struct powerdomain gfx_omap2_pwrdm;
255 269
270extern void pwrdm_lock(struct powerdomain *pwrdm);
271extern void pwrdm_unlock(struct powerdomain *pwrdm);
256 272
257#endif 273#endif
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
index d3a5399091ad..7b946f1005b1 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
@@ -54,12 +54,12 @@ struct powerdomain gfx_omap2_pwrdm = {
54 .pwrsts_mem_on = { 54 .pwrsts_mem_on = {
55 [0] = PWRSTS_ON, /* MEMONSTATE */ 55 [0] = PWRSTS_ON, /* MEMONSTATE */
56 }, 56 },
57 .voltdm = { .name = "core" }, 57 .voltdm = { .name = "core" },
58}; 58};
59 59
60struct powerdomain wkup_omap2_pwrdm = { 60struct powerdomain wkup_omap2_pwrdm = {
61 .name = "wkup_pwrdm", 61 .name = "wkup_pwrdm",
62 .prcm_offs = WKUP_MOD, 62 .prcm_offs = WKUP_MOD,
63 .pwrsts = PWRSTS_ON, 63 .pwrsts = PWRSTS_ON,
64 .voltdm = { .name = "wakeup" }, 64 .voltdm = { .name = "wakeup" },
65}; 65};
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c
index ba520d4f7c7b..578eef86fcf2 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
@@ -38,7 +38,7 @@ static struct powerdomain dsp_pwrdm = {
38 .pwrsts_mem_on = { 38 .pwrsts_mem_on = {
39 [0] = PWRSTS_ON, 39 [0] = PWRSTS_ON,
40 }, 40 },
41 .voltdm = { .name = "core" }, 41 .voltdm = { .name = "core" },
42}; 42};
43 43
44static struct powerdomain mpu_24xx_pwrdm = { 44static struct powerdomain mpu_24xx_pwrdm = {
@@ -53,13 +53,14 @@ static struct powerdomain mpu_24xx_pwrdm = {
53 .pwrsts_mem_on = { 53 .pwrsts_mem_on = {
54 [0] = PWRSTS_ON, 54 [0] = PWRSTS_ON,
55 }, 55 },
56 .voltdm = { .name = "core" }, 56 .voltdm = { .name = "core" },
57}; 57};
58 58
59static struct powerdomain core_24xx_pwrdm = { 59static struct powerdomain core_24xx_pwrdm = {
60 .name = "core_pwrdm", 60 .name = "core_pwrdm",
61 .prcm_offs = CORE_MOD, 61 .prcm_offs = CORE_MOD,
62 .pwrsts = PWRSTS_OFF_RET_ON, 62 .pwrsts = PWRSTS_OFF_RET_ON,
63 .pwrsts_logic_ret = PWRSTS_RET,
63 .banks = 3, 64 .banks = 3,
64 .pwrsts_mem_ret = { 65 .pwrsts_mem_ret = {
65 [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ 66 [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
@@ -71,7 +72,7 @@ static struct powerdomain core_24xx_pwrdm = {
71 [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ 72 [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
72 [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */ 73 [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
73 }, 74 },
74 .voltdm = { .name = "core" }, 75 .voltdm = { .name = "core" },
75}; 76};
76 77
77 78
@@ -93,7 +94,7 @@ static struct powerdomain mdm_pwrdm = {
93 .pwrsts_mem_on = { 94 .pwrsts_mem_on = {
94 [0] = PWRSTS_ON, /* MEMONSTATE */ 95 [0] = PWRSTS_ON, /* MEMONSTATE */
95 }, 96 },
96 .voltdm = { .name = "core" }, 97 .voltdm = { .name = "core" },
97}; 98};
98 99
99/* 100/*
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index 8b23d234fb55..f0e14e9efe5a 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -50,7 +50,7 @@ static struct powerdomain iva2_pwrdm = {
50 [2] = PWRSTS_OFF_ON, 50 [2] = PWRSTS_OFF_ON,
51 [3] = PWRSTS_ON, 51 [3] = PWRSTS_ON,
52 }, 52 },
53 .voltdm = { .name = "mpu_iva" }, 53 .voltdm = { .name = "mpu_iva" },
54}; 54};
55 55
56static struct powerdomain mpu_3xxx_pwrdm = { 56static struct powerdomain mpu_3xxx_pwrdm = {
@@ -66,7 +66,7 @@ static struct powerdomain mpu_3xxx_pwrdm = {
66 .pwrsts_mem_on = { 66 .pwrsts_mem_on = {
67 [0] = PWRSTS_OFF_ON, 67 [0] = PWRSTS_OFF_ON,
68 }, 68 },
69 .voltdm = { .name = "mpu_iva" }, 69 .voltdm = { .name = "mpu_iva" },
70}; 70};
71 71
72static struct powerdomain mpu_am35x_pwrdm = { 72static struct powerdomain mpu_am35x_pwrdm = {
@@ -82,7 +82,7 @@ static struct powerdomain mpu_am35x_pwrdm = {
82 .pwrsts_mem_on = { 82 .pwrsts_mem_on = {
83 [0] = PWRSTS_ON, 83 [0] = PWRSTS_ON,
84 }, 84 },
85 .voltdm = { .name = "mpu_iva" }, 85 .voltdm = { .name = "mpu_iva" },
86}; 86};
87 87
88/* 88/*
@@ -109,7 +109,7 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
109 [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ 109 [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
110 [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ 110 [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
111 }, 111 },
112 .voltdm = { .name = "core" }, 112 .voltdm = { .name = "core" },
113}; 113};
114 114
115static struct powerdomain core_3xxx_es3_1_pwrdm = { 115static struct powerdomain core_3xxx_es3_1_pwrdm = {
@@ -131,7 +131,7 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
131 [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ 131 [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
132 [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ 132 [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
133 }, 133 },
134 .voltdm = { .name = "core" }, 134 .voltdm = { .name = "core" },
135}; 135};
136 136
137static struct powerdomain core_am35x_pwrdm = { 137static struct powerdomain core_am35x_pwrdm = {
@@ -148,7 +148,7 @@ static struct powerdomain core_am35x_pwrdm = {
148 [0] = PWRSTS_ON, /* MEM1ONSTATE */ 148 [0] = PWRSTS_ON, /* MEM1ONSTATE */
149 [1] = PWRSTS_ON, /* MEM2ONSTATE */ 149 [1] = PWRSTS_ON, /* MEM2ONSTATE */
150 }, 150 },
151 .voltdm = { .name = "core" }, 151 .voltdm = { .name = "core" },
152}; 152};
153 153
154static struct powerdomain dss_pwrdm = { 154static struct powerdomain dss_pwrdm = {
@@ -163,7 +163,7 @@ static struct powerdomain dss_pwrdm = {
163 .pwrsts_mem_on = { 163 .pwrsts_mem_on = {
164 [0] = PWRSTS_ON, /* MEMONSTATE */ 164 [0] = PWRSTS_ON, /* MEMONSTATE */
165 }, 165 },
166 .voltdm = { .name = "core" }, 166 .voltdm = { .name = "core" },
167}; 167};
168 168
169static struct powerdomain dss_am35x_pwrdm = { 169static struct powerdomain dss_am35x_pwrdm = {
@@ -178,7 +178,7 @@ static struct powerdomain dss_am35x_pwrdm = {
178 .pwrsts_mem_on = { 178 .pwrsts_mem_on = {
179 [0] = PWRSTS_ON, /* MEMONSTATE */ 179 [0] = PWRSTS_ON, /* MEMONSTATE */
180 }, 180 },
181 .voltdm = { .name = "core" }, 181 .voltdm = { .name = "core" },
182}; 182};
183 183
184/* 184/*
@@ -199,7 +199,7 @@ static struct powerdomain sgx_pwrdm = {
199 .pwrsts_mem_on = { 199 .pwrsts_mem_on = {
200 [0] = PWRSTS_ON, /* MEMONSTATE */ 200 [0] = PWRSTS_ON, /* MEMONSTATE */
201 }, 201 },
202 .voltdm = { .name = "core" }, 202 .voltdm = { .name = "core" },
203}; 203};
204 204
205static struct powerdomain sgx_am35x_pwrdm = { 205static struct powerdomain sgx_am35x_pwrdm = {
@@ -214,7 +214,7 @@ static struct powerdomain sgx_am35x_pwrdm = {
214 .pwrsts_mem_on = { 214 .pwrsts_mem_on = {
215 [0] = PWRSTS_ON, /* MEMONSTATE */ 215 [0] = PWRSTS_ON, /* MEMONSTATE */
216 }, 216 },
217 .voltdm = { .name = "core" }, 217 .voltdm = { .name = "core" },
218}; 218};
219 219
220static struct powerdomain cam_pwrdm = { 220static struct powerdomain cam_pwrdm = {
@@ -229,7 +229,7 @@ static struct powerdomain cam_pwrdm = {
229 .pwrsts_mem_on = { 229 .pwrsts_mem_on = {
230 [0] = PWRSTS_ON, /* MEMONSTATE */ 230 [0] = PWRSTS_ON, /* MEMONSTATE */
231 }, 231 },
232 .voltdm = { .name = "core" }, 232 .voltdm = { .name = "core" },
233}; 233};
234 234
235static struct powerdomain per_pwrdm = { 235static struct powerdomain per_pwrdm = {
@@ -244,7 +244,7 @@ static struct powerdomain per_pwrdm = {
244 .pwrsts_mem_on = { 244 .pwrsts_mem_on = {
245 [0] = PWRSTS_ON, /* MEMONSTATE */ 245 [0] = PWRSTS_ON, /* MEMONSTATE */
246 }, 246 },
247 .voltdm = { .name = "core" }, 247 .voltdm = { .name = "core" },
248}; 248};
249 249
250static struct powerdomain per_am35x_pwrdm = { 250static struct powerdomain per_am35x_pwrdm = {
@@ -259,13 +259,13 @@ static struct powerdomain per_am35x_pwrdm = {
259 .pwrsts_mem_on = { 259 .pwrsts_mem_on = {
260 [0] = PWRSTS_ON, /* MEMONSTATE */ 260 [0] = PWRSTS_ON, /* MEMONSTATE */
261 }, 261 },
262 .voltdm = { .name = "core" }, 262 .voltdm = { .name = "core" },
263}; 263};
264 264
265static struct powerdomain emu_pwrdm = { 265static struct powerdomain emu_pwrdm = {
266 .name = "emu_pwrdm", 266 .name = "emu_pwrdm",
267 .prcm_offs = OMAP3430_EMU_MOD, 267 .prcm_offs = OMAP3430_EMU_MOD,
268 .voltdm = { .name = "core" }, 268 .voltdm = { .name = "core" },
269}; 269};
270 270
271static struct powerdomain neon_pwrdm = { 271static struct powerdomain neon_pwrdm = {
@@ -273,7 +273,7 @@ static struct powerdomain neon_pwrdm = {
273 .prcm_offs = OMAP3430_NEON_MOD, 273 .prcm_offs = OMAP3430_NEON_MOD,
274 .pwrsts = PWRSTS_OFF_RET_ON, 274 .pwrsts = PWRSTS_OFF_RET_ON,
275 .pwrsts_logic_ret = PWRSTS_RET, 275 .pwrsts_logic_ret = PWRSTS_RET,
276 .voltdm = { .name = "mpu_iva" }, 276 .voltdm = { .name = "mpu_iva" },
277}; 277};
278 278
279static struct powerdomain neon_am35x_pwrdm = { 279static struct powerdomain neon_am35x_pwrdm = {
@@ -281,7 +281,7 @@ static struct powerdomain neon_am35x_pwrdm = {
281 .prcm_offs = OMAP3430_NEON_MOD, 281 .prcm_offs = OMAP3430_NEON_MOD,
282 .pwrsts = PWRSTS_ON, 282 .pwrsts = PWRSTS_ON,
283 .pwrsts_logic_ret = PWRSTS_ON, 283 .pwrsts_logic_ret = PWRSTS_ON,
284 .voltdm = { .name = "mpu_iva" }, 284 .voltdm = { .name = "mpu_iva" },
285}; 285};
286 286
287static struct powerdomain usbhost_pwrdm = { 287static struct powerdomain usbhost_pwrdm = {
@@ -303,37 +303,37 @@ static struct powerdomain usbhost_pwrdm = {
303 .pwrsts_mem_on = { 303 .pwrsts_mem_on = {
304 [0] = PWRSTS_ON, /* MEMONSTATE */ 304 [0] = PWRSTS_ON, /* MEMONSTATE */
305 }, 305 },
306 .voltdm = { .name = "core" }, 306 .voltdm = { .name = "core" },
307}; 307};
308 308
309static struct powerdomain dpll1_pwrdm = { 309static struct powerdomain dpll1_pwrdm = {
310 .name = "dpll1_pwrdm", 310 .name = "dpll1_pwrdm",
311 .prcm_offs = MPU_MOD, 311 .prcm_offs = MPU_MOD,
312 .voltdm = { .name = "mpu_iva" }, 312 .voltdm = { .name = "mpu_iva" },
313}; 313};
314 314
315static struct powerdomain dpll2_pwrdm = { 315static struct powerdomain dpll2_pwrdm = {
316 .name = "dpll2_pwrdm", 316 .name = "dpll2_pwrdm",
317 .prcm_offs = OMAP3430_IVA2_MOD, 317 .prcm_offs = OMAP3430_IVA2_MOD,
318 .voltdm = { .name = "mpu_iva" }, 318 .voltdm = { .name = "mpu_iva" },
319}; 319};
320 320
321static struct powerdomain dpll3_pwrdm = { 321static struct powerdomain dpll3_pwrdm = {
322 .name = "dpll3_pwrdm", 322 .name = "dpll3_pwrdm",
323 .prcm_offs = PLL_MOD, 323 .prcm_offs = PLL_MOD,
324 .voltdm = { .name = "core" }, 324 .voltdm = { .name = "core" },
325}; 325};
326 326
327static struct powerdomain dpll4_pwrdm = { 327static struct powerdomain dpll4_pwrdm = {
328 .name = "dpll4_pwrdm", 328 .name = "dpll4_pwrdm",
329 .prcm_offs = PLL_MOD, 329 .prcm_offs = PLL_MOD,
330 .voltdm = { .name = "core" }, 330 .voltdm = { .name = "core" },
331}; 331};
332 332
333static struct powerdomain dpll5_pwrdm = { 333static struct powerdomain dpll5_pwrdm = {
334 .name = "dpll5_pwrdm", 334 .name = "dpll5_pwrdm",
335 .prcm_offs = PLL_MOD, 335 .prcm_offs = PLL_MOD,
336 .voltdm = { .name = "core" }, 336 .voltdm = { .name = "core" },
337}; 337};
338 338
339/* As powerdomains are added or removed above, this list must also be changed */ 339/* As powerdomains are added or removed above, this list must also be changed */
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index a3e121f94a86..947f6adfed0c 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -210,6 +210,7 @@ int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
210 PM_WKDEP, (1 << clkdm2->dep_bit)); 210 PM_WKDEP, (1 << clkdm2->dep_bit));
211} 211}
212 212
213/* XXX Caller must hold the clkdm's powerdomain lock */
213int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) 214int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
214{ 215{
215 struct clkdm_dep *cd; 216 struct clkdm_dep *cd;
@@ -221,7 +222,7 @@ int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
221 222
222 /* PRM accesses are slow, so minimize them */ 223 /* PRM accesses are slow, so minimize them */
223 mask |= 1 << cd->clkdm->dep_bit; 224 mask |= 1 << cd->clkdm->dep_bit;
224 atomic_set(&cd->wkdep_usecount, 0); 225 cd->wkdep_usecount = 0;
225 } 226 }
226 227
227 omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, 228 omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 24e9ad3cb993..8396b5b7e912 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -316,8 +316,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
316 if (WARN_ON(!oh)) 316 if (WARN_ON(!oh))
317 return; 317 return;
318 318
319 pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size, 319 pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size);
320 NULL, 0, false);
321 if (IS_ERR(pdev)) { 320 if (IS_ERR(pdev)) {
322 WARN(1, "Could not build omap_device for %s: %s.\n", name, 321 WARN(1, "Could not build omap_device for %s: %s.\n", name,
323 oh->name); 322 oh->name);
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index b9753fe27232..bb829e065400 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -152,8 +152,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
152 152
153 sr_data->enable_on_init = sr_enable_on_init; 153 sr_data->enable_on_init = sr_enable_on_init;
154 154
155 pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), 155 pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), 0);
156 NULL, 0, 0);
157 if (IS_ERR(pdev)) 156 if (IS_ERR(pdev))
158 pr_warning("%s: Could not build omap_device for %s: %s.\n\n", 157 pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
159 __func__, name, oh->name); 158 __func__, name, oh->name);
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 72c2ca1e3f70..2bdd4cf17a8f 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -683,8 +683,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
683 pdata->timer_errata = omap_dm_timer_get_errata(); 683 pdata->timer_errata = omap_dm_timer_get_errata();
684 pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; 684 pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
685 685
686 pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), 686 pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata));
687 NULL, 0, 0);
688 687
689 if (IS_ERR(pdev)) { 688 if (IS_ERR(pdev)) {
690 pr_err("%s: Can't build omap_device for %s: %s.\n", 689 pr_err("%s: Can't build omap_device for %s: %s.\n",
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 2e44e8a22884..5706bdccf45e 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -37,19 +37,6 @@
37#define USBHS_UHH_HWMODNAME "usb_host_hs" 37#define USBHS_UHH_HWMODNAME "usb_host_hs"
38#define USBHS_TLL_HWMODNAME "usb_tll_hs" 38#define USBHS_TLL_HWMODNAME "usb_tll_hs"
39 39
40static struct usbhs_omap_platform_data usbhs_data;
41static struct usbtll_omap_platform_data usbtll_data;
42static struct ehci_hcd_omap_platform_data ehci_data;
43static struct ohci_hcd_omap_platform_data ohci_data;
44
45static struct omap_device_pm_latency omap_uhhtll_latency[] = {
46 {
47 .deactivate_func = omap_device_idle_hwmods,
48 .activate_func = omap_device_enable_hwmods,
49 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
50 },
51};
52
53/* MUX settings for EHCI pins */ 40/* MUX settings for EHCI pins */
54/* 41/*
55 * setup_ehci_io_mux - initialize IO pad mux for USBHOST 42 * setup_ehci_io_mux - initialize IO pad mux for USBHOST
@@ -485,32 +472,18 @@ void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
485 } 472 }
486} 473}
487 474
488void __init usbhs_init(const struct usbhs_omap_board_data *pdata) 475void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
489{ 476{
490 struct omap_hwmod *uhh_hwm, *tll_hwm; 477 struct omap_hwmod *uhh_hwm, *tll_hwm;
491 struct platform_device *pdev; 478 struct platform_device *pdev;
492 int bus_id = -1; 479 int bus_id = -1;
493 int i;
494
495 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
496 usbhs_data.port_mode[i] = pdata->port_mode[i];
497 usbtll_data.port_mode[i] = pdata->port_mode[i];
498 ohci_data.port_mode[i] = pdata->port_mode[i];
499 ehci_data.port_mode[i] = pdata->port_mode[i];
500 ehci_data.reset_gpio_port[i] = pdata->reset_gpio_port[i];
501 ehci_data.regulator[i] = pdata->regulator[i];
502 }
503 ehci_data.phy_reset = pdata->phy_reset;
504 ohci_data.es2_compatibility = pdata->es2_compatibility;
505 usbhs_data.ehci_data = &ehci_data;
506 usbhs_data.ohci_data = &ohci_data;
507 480
508 if (cpu_is_omap34xx()) { 481 if (cpu_is_omap34xx()) {
509 setup_ehci_io_mux(pdata->port_mode); 482 setup_ehci_io_mux(pdata->port_mode);
510 setup_ohci_io_mux(pdata->port_mode); 483 setup_ohci_io_mux(pdata->port_mode);
511 484
512 if (omap_rev() <= OMAP3430_REV_ES2_1) 485 if (omap_rev() <= OMAP3430_REV_ES2_1)
513 usbhs_data.single_ulpi_bypass = true; 486 pdata->single_ulpi_bypass = true;
514 487
515 } else if (cpu_is_omap44xx()) { 488 } else if (cpu_is_omap44xx()) {
516 setup_4430ehci_io_mux(pdata->port_mode); 489 setup_4430ehci_io_mux(pdata->port_mode);
@@ -530,9 +503,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
530 } 503 }
531 504
532 pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm, 505 pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
533 &usbtll_data, sizeof(usbtll_data), 506 pdata, sizeof(*pdata));
534 omap_uhhtll_latency,
535 ARRAY_SIZE(omap_uhhtll_latency), false);
536 if (IS_ERR(pdev)) { 507 if (IS_ERR(pdev)) {
537 pr_err("Could not build hwmod device %s\n", 508 pr_err("Could not build hwmod device %s\n",
538 USBHS_TLL_HWMODNAME); 509 USBHS_TLL_HWMODNAME);
@@ -540,9 +511,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
540 } 511 }
541 512
542 pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm, 513 pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
543 &usbhs_data, sizeof(usbhs_data), 514 pdata, sizeof(*pdata));
544 omap_uhhtll_latency,
545 ARRAY_SIZE(omap_uhhtll_latency), false);
546 if (IS_ERR(pdev)) { 515 if (IS_ERR(pdev)) {
547 pr_err("Could not build hwmod devices %s\n", 516 pr_err("Could not build hwmod devices %s\n",
548 USBHS_UHH_HWMODNAME); 517 USBHS_UHH_HWMODNAME);
@@ -552,7 +521,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
552 521
553#else 522#else
554 523
555void __init usbhs_init(const struct usbhs_omap_board_data *pdata) 524void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
556{ 525{
557} 526}
558 527
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 9d27e3f8a09c..3242a554ad6b 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -105,7 +105,7 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
105 return; 105 return;
106 106
107 pdev = omap_device_build(name, bus_id, oh, &musb_plat, 107 pdev = omap_device_build(name, bus_id, oh, &musb_plat,
108 sizeof(musb_plat), NULL, 0, false); 108 sizeof(musb_plat));
109 if (IS_ERR(pdev)) { 109 if (IS_ERR(pdev)) {
110 pr_err("Could not build omap_device for %s %s\n", 110 pr_err("Could not build omap_device for %s %s\n",
111 name, oh_name); 111 name, oh_name);
diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h
index 9b986ead7c45..3319f5cf47a3 100644
--- a/arch/arm/mach-omap2/usb.h
+++ b/arch/arm/mach-omap2/usb.h
@@ -53,26 +53,8 @@
53#define USBPHY_OTGSESSEND_EN (1 << 20) 53#define USBPHY_OTGSESSEND_EN (1 << 20)
54#define USBPHY_DATA_POLARITY (1 << 23) 54#define USBPHY_DATA_POLARITY (1 << 23)
55 55
56struct usbhs_omap_board_data {
57 enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
58
59 /* have to be valid if phy_reset is true and portx is in phy mode */
60 int reset_gpio_port[OMAP3_HS_USB_PORTS];
61
62 /* Set this to true for ES2.x silicon */
63 unsigned es2_compatibility:1;
64
65 unsigned phy_reset:1;
66
67 /*
68 * Regulators for USB PHYs.
69 * Each PHY can have a separate regulator.
70 */
71 struct regulator *regulator[OMAP3_HS_USB_PORTS];
72};
73
74extern void usb_musb_init(struct omap_musb_board_data *board_data); 56extern void usb_musb_init(struct omap_musb_board_data *board_data);
75extern void usbhs_init(const struct usbhs_omap_board_data *pdata); 57extern void usbhs_init(struct usbhs_omap_platform_data *pdata);
76 58
77extern void am35x_musb_reset(void); 59extern void am35x_musb_reset(void);
78extern void am35x_musb_phy_power(u8 on); 60extern void am35x_musb_phy_power(u8 on);
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
index 70240a54995c..d15c7bbab8e2 100644
--- a/arch/arm/mach-omap2/wd_timer.c
+++ b/arch/arm/mach-omap2/wd_timer.c
@@ -124,8 +124,7 @@ static int __init omap_init_wdt(void)
124 pdata.read_reset_sources = prm_read_reset_sources; 124 pdata.read_reset_sources = prm_read_reset_sources;
125 125
126 pdev = omap_device_build(dev_name, id, oh, &pdata, 126 pdev = omap_device_build(dev_name, id, oh, &pdata,
127 sizeof(struct omap_wd_timer_platform_data), 127 sizeof(struct omap_wd_timer_platform_data));
128 NULL, 0, 0);
129 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", 128 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
130 dev_name, oh->name); 129 dev_name, oh->name);
131 return 0; 130 return 0;
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig
index 558ccfb8d458..4f7379fe01e2 100644
--- a/arch/arm/mach-prima2/Kconfig
+++ b/arch/arm/mach-prima2/Kconfig
@@ -11,6 +11,16 @@ config ARCH_PRIMA2
11 help 11 help
12 Support for CSR SiRFSoC ARM Cortex A9 Platform 12 Support for CSR SiRFSoC ARM Cortex A9 Platform
13 13
14config ARCH_MARCO
15 bool "CSR SiRFSoC MARCO ARM Cortex A9 Platform"
16 default y
17 select ARM_GIC
18 select CPU_V7
19 select HAVE_SMP
20 select SMP_ON_UP
21 help
22 Support for CSR SiRFSoC ARM Cortex A9 Platform
23
14endmenu 24endmenu
15 25
16config SIRF_IRQ 26config SIRF_IRQ
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
index fc9ce22e2b5a..bfe360cbd177 100644
--- a/arch/arm/mach-prima2/Makefile
+++ b/arch/arm/mach-prima2/Makefile
@@ -1,4 +1,3 @@
1obj-y := timer.o
2obj-y += rstc.o 1obj-y += rstc.o
3obj-y += common.o 2obj-y += common.o
4obj-y += rtciobrg.o 3obj-y += rtciobrg.o
@@ -6,3 +5,7 @@ obj-$(CONFIG_DEBUG_LL) += lluart.o
6obj-$(CONFIG_CACHE_L2X0) += l2x0.o 5obj-$(CONFIG_CACHE_L2X0) += l2x0.o
7obj-$(CONFIG_SUSPEND) += pm.o sleep.o 6obj-$(CONFIG_SUSPEND) += pm.o sleep.o
8obj-$(CONFIG_SIRF_IRQ) += irq.o 7obj-$(CONFIG_SIRF_IRQ) += irq.o
8obj-$(CONFIG_SMP) += platsmp.o headsmp.o
9obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
10obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o
11obj-$(CONFIG_ARCH_MARCO) += timer-marco.o
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c
index ed3570e5eb8f..2d57aa479a7b 100644
--- a/arch/arm/mach-prima2/common.c
+++ b/arch/arm/mach-prima2/common.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/irqchip.h>
11#include <asm/sizes.h> 12#include <asm/sizes.h>
12#include <asm/mach-types.h> 13#include <asm/mach-types.h>
13#include <asm/mach/arch.h> 14#include <asm/mach/arch.h>
@@ -30,6 +31,12 @@ void __init sirfsoc_init_late(void)
30 sirfsoc_pm_init(); 31 sirfsoc_pm_init();
31} 32}
32 33
34static __init void sirfsoc_map_io(void)
35{
36 sirfsoc_map_lluart();
37 sirfsoc_map_scu();
38}
39
33#ifdef CONFIG_ARCH_PRIMA2 40#ifdef CONFIG_ARCH_PRIMA2
34static const char *prima2_dt_match[] __initdata = { 41static const char *prima2_dt_match[] __initdata = {
35 "sirf,prima2", 42 "sirf,prima2",
@@ -38,9 +45,12 @@ static const char *prima2_dt_match[] __initdata = {
38 45
39DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") 46DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)")
40 /* Maintainer: Barry Song <baohua.song@csr.com> */ 47 /* Maintainer: Barry Song <baohua.song@csr.com> */
41 .map_io = sirfsoc_map_lluart, 48 .map_io = sirfsoc_map_io,
42 .init_irq = sirfsoc_of_irq_init, 49 .init_irq = sirfsoc_of_irq_init,
43 .init_time = sirfsoc_timer_init, 50 .init_time = sirfsoc_prima2_timer_init,
51#ifdef CONFIG_MULTI_IRQ_HANDLER
52 .handle_irq = sirfsoc_handle_irq,
53#endif
44 .dma_zone_size = SZ_256M, 54 .dma_zone_size = SZ_256M,
45 .init_machine = sirfsoc_mach_init, 55 .init_machine = sirfsoc_mach_init,
46 .init_late = sirfsoc_init_late, 56 .init_late = sirfsoc_init_late,
@@ -48,3 +58,22 @@ DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)")
48 .restart = sirfsoc_restart, 58 .restart = sirfsoc_restart,
49MACHINE_END 59MACHINE_END
50#endif 60#endif
61
62#ifdef CONFIG_ARCH_MARCO
63static const char *marco_dt_match[] __initdata = {
64 "sirf,marco",
65 NULL
66};
67
68DT_MACHINE_START(MARCO_DT, "Generic MARCO (Flattened Device Tree)")
69 /* Maintainer: Barry Song <baohua.song@csr.com> */
70 .smp = smp_ops(sirfsoc_smp_ops),
71 .map_io = sirfsoc_map_io,
72 .init_irq = irqchip_init,
73 .init_time = sirfsoc_marco_timer_init,
74 .init_machine = sirfsoc_mach_init,
75 .init_late = sirfsoc_init_late,
76 .dt_compat = marco_dt_match,
77 .restart = sirfsoc_restart,
78MACHINE_END
79#endif
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
index 9c75f124e3cf..b7c26b62e4a7 100644
--- a/arch/arm/mach-prima2/common.h
+++ b/arch/arm/mach-prima2/common.h
@@ -11,12 +11,19 @@
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <asm/mach/time.h> 13#include <asm/mach/time.h>
14#include <asm/exception.h>
14 15
15extern void sirfsoc_timer_init(void); 16extern void sirfsoc_prima2_timer_init(void);
17extern void sirfsoc_marco_timer_init(void);
18
19extern struct smp_operations sirfsoc_smp_ops;
20extern void sirfsoc_secondary_startup(void);
21extern void sirfsoc_cpu_die(unsigned int cpu);
16 22
17extern void __init sirfsoc_of_irq_init(void); 23extern void __init sirfsoc_of_irq_init(void);
18extern void __init sirfsoc_of_clk_init(void); 24extern void __init sirfsoc_of_clk_init(void);
19extern void sirfsoc_restart(char, const char *); 25extern void sirfsoc_restart(char, const char *);
26extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs);
20 27
21#ifndef CONFIG_DEBUG_LL 28#ifndef CONFIG_DEBUG_LL
22static inline void sirfsoc_map_lluart(void) {} 29static inline void sirfsoc_map_lluart(void) {}
@@ -24,6 +31,12 @@ static inline void sirfsoc_map_lluart(void) {}
24extern void __init sirfsoc_map_lluart(void); 31extern void __init sirfsoc_map_lluart(void);
25#endif 32#endif
26 33
34#ifndef CONFIG_SMP
35static inline void sirfsoc_map_scu(void) {}
36#else
37extern void sirfsoc_map_scu(void);
38#endif
39
27#ifdef CONFIG_SUSPEND 40#ifdef CONFIG_SUSPEND
28extern int sirfsoc_pm_init(void); 41extern int sirfsoc_pm_init(void);
29#else 42#else
diff --git a/arch/arm/mach-prima2/headsmp.S b/arch/arm/mach-prima2/headsmp.S
new file mode 100644
index 000000000000..5b8a408d8921
--- /dev/null
+++ b/arch/arm/mach-prima2/headsmp.S
@@ -0,0 +1,40 @@
1/*
2 * Entry of the second core for CSR Marco dual-core SMP SoCs
3 *
4 * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/linkage.h>
10#include <linux/init.h>
11
12 __CPUINIT
13
14/*
15 * SIRFSOC specific entry point for secondary CPUs. This provides
16 * a "holding pen" into which all secondary cores are held until we're
17 * ready for them to initialise.
18 */
19ENTRY(sirfsoc_secondary_startup)
20 bl v7_invalidate_l1
21 mrc p15, 0, r0, c0, c0, 5
22 and r0, r0, #15
23 adr r4, 1f
24 ldmia r4, {r5, r6}
25 sub r4, r4, r5
26 add r6, r6, r4
27pen: ldr r7, [r6]
28 cmp r7, r0
29 bne pen
30
31 /*
32 * we've been released from the holding pen: secondary_stack
33 * should now contain the SVC stack for this core
34 */
35 b secondary_startup
36ENDPROC(sirfsoc_secondary_startup)
37
38 .align
391: .long .
40 .long pen_release
diff --git a/arch/arm/mach-prima2/hotplug.c b/arch/arm/mach-prima2/hotplug.c
new file mode 100644
index 000000000000..f4b17cbababd
--- /dev/null
+++ b/arch/arm/mach-prima2/hotplug.c
@@ -0,0 +1,41 @@
1/*
2 * CPU hotplug support for CSR Marco dual-core SMP SoCs
3 *
4 * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/kernel.h>
10#include <linux/errno.h>
11#include <linux/smp.h>
12
13#include <asm/cacheflush.h>
14#include <asm/smp_plat.h>
15
16static inline void platform_do_lowpower(unsigned int cpu)
17{
18 flush_cache_all();
19
20 /* we put the platform to just WFI */
21 for (;;) {
22 __asm__ __volatile__("dsb\n\t" "wfi\n\t"
23 : : : "memory");
24 if (pen_release == cpu_logical_map(cpu)) {
25 /*
26 * OK, proper wakeup, we're done
27 */
28 break;
29 }
30 }
31}
32
33/*
34 * platform-specific code to shutdown a CPU
35 *
36 * Called with IRQs disabled
37 */
38void __ref sirfsoc_cpu_die(unsigned int cpu)
39{
40 platform_do_lowpower(cpu);
41}
diff --git a/arch/arm/mach-prima2/include/mach/irqs.h b/arch/arm/mach-prima2/include/mach/irqs.h
index f6014a07541f..b778a0f248ed 100644
--- a/arch/arm/mach-prima2/include/mach/irqs.h
+++ b/arch/arm/mach-prima2/include/mach/irqs.h
@@ -10,8 +10,8 @@
10#define __ASM_ARCH_IRQS_H 10#define __ASM_ARCH_IRQS_H
11 11
12#define SIRFSOC_INTENAL_IRQ_START 0 12#define SIRFSOC_INTENAL_IRQ_START 0
13#define SIRFSOC_INTENAL_IRQ_END 59 13#define SIRFSOC_INTENAL_IRQ_END 127
14#define SIRFSOC_GPIO_IRQ_START (SIRFSOC_INTENAL_IRQ_END + 1) 14#define SIRFSOC_GPIO_IRQ_START (SIRFSOC_INTENAL_IRQ_END + 1)
15#define NR_IRQS 220 15#define NR_IRQS 288
16 16
17#endif 17#endif
diff --git a/arch/arm/mach-prima2/include/mach/uart.h b/arch/arm/mach-prima2/include/mach/uart.h
index c98b4d5ac24a..c10510d01a44 100644
--- a/arch/arm/mach-prima2/include/mach/uart.h
+++ b/arch/arm/mach-prima2/include/mach/uart.h
@@ -10,7 +10,13 @@
10#define __MACH_PRIMA2_SIRFSOC_UART_H 10#define __MACH_PRIMA2_SIRFSOC_UART_H
11 11
12/* UART-1: used as serial debug port */ 12/* UART-1: used as serial debug port */
13#if defined(CONFIG_DEBUG_SIRFPRIMA2_UART1)
13#define SIRFSOC_UART1_PA_BASE 0xb0060000 14#define SIRFSOC_UART1_PA_BASE 0xb0060000
15#elif defined(CONFIG_DEBUG_SIRFMARCO_UART1)
16#define SIRFSOC_UART1_PA_BASE 0xcc060000
17#else
18#define SIRFSOC_UART1_PA_BASE 0
19#endif
14#define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000) 20#define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000)
15#define SIRFSOC_UART1_SIZE SZ_4K 21#define SIRFSOC_UART1_SIZE SZ_4K
16 22
diff --git a/arch/arm/mach-prima2/include/mach/uncompress.h b/arch/arm/mach-prima2/include/mach/uncompress.h
index f72ca26ab4fe..d1513a33709a 100644
--- a/arch/arm/mach-prima2/include/mach/uncompress.h
+++ b/arch/arm/mach-prima2/include/mach/uncompress.h
@@ -23,6 +23,9 @@ static __inline__ void putc(char c)
23 * during kernel decompression, all mappings are flat: 23 * during kernel decompression, all mappings are flat:
24 * virt_addr == phys_addr 24 * virt_addr == phys_addr
25 */ 25 */
26 if (!SIRFSOC_UART1_PA_BASE)
27 return;
28
26 while (__raw_readl((void __iomem *)SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS) 29 while (__raw_readl((void __iomem *)SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS)
27 & SIRFSOC_UART1_TXFIFO_FULL) 30 & SIRFSOC_UART1_TXFIFO_FULL)
28 barrier(); 31 barrier();
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c
index 7dee9176e77a..6c0f3e9c43fb 100644
--- a/arch/arm/mach-prima2/irq.c
+++ b/arch/arm/mach-prima2/irq.c
@@ -9,17 +9,19 @@
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/io.h> 10#include <linux/io.h>
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <mach/hardware.h>
13#include <asm/mach/irq.h>
14#include <linux/of.h> 12#include <linux/of.h>
15#include <linux/of_address.h> 13#include <linux/of_address.h>
16#include <linux/irqdomain.h> 14#include <linux/irqdomain.h>
17#include <linux/syscore_ops.h> 15#include <linux/syscore_ops.h>
16#include <asm/mach/irq.h>
17#include <asm/exception.h>
18#include <mach/hardware.h>
18 19
19#define SIRFSOC_INT_RISC_MASK0 0x0018 20#define SIRFSOC_INT_RISC_MASK0 0x0018
20#define SIRFSOC_INT_RISC_MASK1 0x001C 21#define SIRFSOC_INT_RISC_MASK1 0x001C
21#define SIRFSOC_INT_RISC_LEVEL0 0x0020 22#define SIRFSOC_INT_RISC_LEVEL0 0x0020
22#define SIRFSOC_INT_RISC_LEVEL1 0x0024 23#define SIRFSOC_INT_RISC_LEVEL1 0x0024
24#define SIRFSOC_INIT_IRQ_ID 0x0038
23 25
24void __iomem *sirfsoc_intc_base; 26void __iomem *sirfsoc_intc_base;
25 27
@@ -52,6 +54,16 @@ static __init void sirfsoc_irq_init(void)
52 writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1); 54 writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1);
53} 55}
54 56
57asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs)
58{
59 u32 irqstat, irqnr;
60
61 irqstat = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INIT_IRQ_ID);
62 irqnr = irqstat & 0xff;
63
64 handle_IRQ(irqnr, regs);
65}
66
55static struct of_device_id intc_ids[] = { 67static struct of_device_id intc_ids[] = {
56 { .compatible = "sirf,prima2-intc" }, 68 { .compatible = "sirf,prima2-intc" },
57 {}, 69 {},
diff --git a/arch/arm/mach-prima2/l2x0.c b/arch/arm/mach-prima2/l2x0.c
index c99837797d76..cbcbe9cb094c 100644
--- a/arch/arm/mach-prima2/l2x0.c
+++ b/arch/arm/mach-prima2/l2x0.c
@@ -11,19 +11,38 @@
11#include <linux/of.h> 11#include <linux/of.h>
12#include <asm/hardware/cache-l2x0.h> 12#include <asm/hardware/cache-l2x0.h>
13 13
14static struct of_device_id prima2_l2x0_ids[] = { 14struct l2x0_aux
15 { .compatible = "sirf,prima2-pl310-cache" }, 15{
16 u32 val;
17 u32 mask;
18};
19
20static struct l2x0_aux prima2_l2x0_aux __initconst = {
21 .val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT,
22 .mask = 0,
23};
24
25static struct l2x0_aux marco_l2x0_aux __initconst = {
26 .val = (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
27 (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT),
28 .mask = L2X0_AUX_CTRL_MASK,
29};
30
31static struct of_device_id sirf_l2x0_ids[] __initconst = {
32 { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
33 { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
16 {}, 34 {},
17}; 35};
18 36
19static int __init sirfsoc_l2x0_init(void) 37static int __init sirfsoc_l2x0_init(void)
20{ 38{
21 struct device_node *np; 39 struct device_node *np;
40 const struct l2x0_aux *aux;
22 41
23 np = of_find_matching_node(NULL, prima2_l2x0_ids); 42 np = of_find_matching_node(NULL, sirf_l2x0_ids);
24 if (np) { 43 if (np) {
25 pr_info("Initializing prima2 L2 cache\n"); 44 aux = of_match_node(sirf_l2x0_ids, np)->data;
26 return l2x0_of_init(0x40000, 0); 45 return l2x0_of_init(aux->val, aux->mask);
27 } 46 }
28 47
29 return 0; 48 return 0;
diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c
new file mode 100644
index 000000000000..4b788310f6a6
--- /dev/null
+++ b/arch/arm/mach-prima2/platsmp.c
@@ -0,0 +1,157 @@
1/*
2 * plat smp support for CSR Marco dual-core SMP SoCs
3 *
4 * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/init.h>
10#include <linux/smp.h>
11#include <linux/delay.h>
12#include <linux/of.h>
13#include <linux/of_address.h>
14#include <linux/irqchip/arm-gic.h>
15#include <asm/page.h>
16#include <asm/mach/map.h>
17#include <asm/smp_plat.h>
18#include <asm/smp_scu.h>
19#include <asm/cacheflush.h>
20#include <asm/cputype.h>
21#include <mach/map.h>
22
23#include "common.h"
24
25static void __iomem *scu_base;
26static void __iomem *rsc_base;
27
28static DEFINE_SPINLOCK(boot_lock);
29
30static struct map_desc scu_io_desc __initdata = {
31 .length = SZ_4K,
32 .type = MT_DEVICE,
33};
34
35void __init sirfsoc_map_scu(void)
36{
37 unsigned long base;
38
39 /* Get SCU base */
40 asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
41
42 scu_io_desc.virtual = SIRFSOC_VA(base);
43 scu_io_desc.pfn = __phys_to_pfn(base);
44 iotable_init(&scu_io_desc, 1);
45
46 scu_base = (void __iomem *)SIRFSOC_VA(base);
47}
48
49static void __cpuinit sirfsoc_secondary_init(unsigned int cpu)
50{
51 /*
52 * if any interrupts are already enabled for the primary
53 * core (e.g. timer irq), then they will not have been enabled
54 * for us: do so
55 */
56 gic_secondary_init(0);
57
58 /*
59 * let the primary processor know we're out of the
60 * pen, then head off into the C entry point
61 */
62 pen_release = -1;
63 smp_wmb();
64
65 /*
66 * Synchronise with the boot thread.
67 */
68 spin_lock(&boot_lock);
69 spin_unlock(&boot_lock);
70}
71
72static struct of_device_id rsc_ids[] = {
73 { .compatible = "sirf,marco-rsc" },
74 {},
75};
76
77static int __cpuinit sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
78{
79 unsigned long timeout;
80 struct device_node *np;
81
82 np = of_find_matching_node(NULL, rsc_ids);
83 if (!np)
84 return -ENODEV;
85
86 rsc_base = of_iomap(np, 0);
87 if (!rsc_base)
88 return -ENOMEM;
89
90 /*
91 * write the address of secondary startup into the sram register
92 * at offset 0x2C, then write the magic number 0x3CAF5D62 to the
93 * RSC register at offset 0x28, which is what boot rom code is
94 * waiting for. This would wake up the secondary core from WFE
95 */
96#define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2C
97 __raw_writel(virt_to_phys(sirfsoc_secondary_startup),
98 rsc_base + SIRFSOC_CPU1_JUMPADDR_OFFSET);
99
100#define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x28
101 __raw_writel(0x3CAF5D62,
102 rsc_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET);
103
104 /* make sure write buffer is drained */
105 mb();
106
107 spin_lock(&boot_lock);
108
109 /*
110 * The secondary processor is waiting to be released from
111 * the holding pen - release it, then wait for it to flag
112 * that it has been released by resetting pen_release.
113 *
114 * Note that "pen_release" is the hardware CPU ID, whereas
115 * "cpu" is Linux's internal ID.
116 */
117 pen_release = cpu_logical_map(cpu);
118 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
119 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
120
121 /*
122 * Send the secondary CPU SEV, thereby causing the boot monitor to read
123 * the JUMPADDR and WAKEMAGIC, and branch to the address found there.
124 */
125 dsb_sev();
126
127 timeout = jiffies + (1 * HZ);
128 while (time_before(jiffies, timeout)) {
129 smp_rmb();
130 if (pen_release == -1)
131 break;
132
133 udelay(10);
134 }
135
136 /*
137 * now the secondary core is starting up let it run its
138 * calibrations, then wait for it to finish
139 */
140 spin_unlock(&boot_lock);
141
142 return pen_release != -1 ? -ENOSYS : 0;
143}
144
145static void __init sirfsoc_smp_prepare_cpus(unsigned int max_cpus)
146{
147 scu_enable(scu_base);
148}
149
150struct smp_operations sirfsoc_smp_ops __initdata = {
151 .smp_prepare_cpus = sirfsoc_smp_prepare_cpus,
152 .smp_secondary_init = sirfsoc_secondary_init,
153 .smp_boot_secondary = sirfsoc_boot_secondary,
154#ifdef CONFIG_HOTPLUG_CPU
155 .cpu_die = sirfsoc_cpu_die,
156#endif
157};
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c
index 762adb73ab7c..435019ca0a48 100644
--- a/arch/arm/mach-prima2/rstc.c
+++ b/arch/arm/mach-prima2/rstc.c
@@ -19,6 +19,7 @@ static DEFINE_MUTEX(rstc_lock);
19 19
20static struct of_device_id rstc_ids[] = { 20static struct of_device_id rstc_ids[] = {
21 { .compatible = "sirf,prima2-rstc" }, 21 { .compatible = "sirf,prima2-rstc" },
22 { .compatible = "sirf,marco-rstc" },
22 {}, 23 {},
23}; 24};
24 25
@@ -42,27 +43,37 @@ early_initcall(sirfsoc_of_rstc_init);
42 43
43int sirfsoc_reset_device(struct device *dev) 44int sirfsoc_reset_device(struct device *dev)
44{ 45{
45 const unsigned int *prop = of_get_property(dev->of_node, "reset-bit", NULL); 46 u32 reset_bit;
46 unsigned int reset_bit;
47 47
48 if (!prop) 48 if (of_property_read_u32(dev->of_node, "reset-bit", &reset_bit))
49 return -ENODEV; 49 return -EINVAL;
50
51 reset_bit = be32_to_cpup(prop);
52 50
53 mutex_lock(&rstc_lock); 51 mutex_lock(&rstc_lock);
54 52
55 /* 53 if (of_device_is_compatible(dev->of_node, "sirf,prima2-rstc")) {
56 * Writing 1 to this bit resets corresponding block. Writing 0 to this 54 /*
57 * bit de-asserts reset signal of the corresponding block. 55 * Writing 1 to this bit resets corresponding block. Writing 0 to this
58 * datasheet doesn't require explicit delay between the set and clear 56 * bit de-asserts reset signal of the corresponding block.
59 * of reset bit. it could be shorter if tests pass. 57 * datasheet doesn't require explicit delay between the set and clear
60 */ 58 * of reset bit. it could be shorter if tests pass.
61 writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, 59 */
62 sirfsoc_rstc_base + (reset_bit / 32) * 4); 60 writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit,
63 msleep(10); 61 sirfsoc_rstc_base + (reset_bit / 32) * 4);
64 writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, 62 msleep(10);
65 sirfsoc_rstc_base + (reset_bit / 32) * 4); 63 writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit,
64 sirfsoc_rstc_base + (reset_bit / 32) * 4);
65 } else {
66 /*
67 * For MARCO and POLO
68 * Writing 1 to SET register resets corresponding block. Writing 1 to CLEAR
69 * register de-asserts reset signal of the corresponding block.
70 * datasheet doesn't require explicit delay between the set and clear
71 * of reset bit. it could be shorter if tests pass.
72 */
73 writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8);
74 msleep(10);
75 writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4);
76 }
66 77
67 mutex_unlock(&rstc_lock); 78 mutex_unlock(&rstc_lock);
68 79
diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c
index 557353602130..9f2da2eec4dc 100644
--- a/arch/arm/mach-prima2/rtciobrg.c
+++ b/arch/arm/mach-prima2/rtciobrg.c
@@ -104,6 +104,7 @@ EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_writel);
104 104
105static const struct of_device_id rtciobrg_ids[] = { 105static const struct of_device_id rtciobrg_ids[] = {
106 { .compatible = "sirf,prima2-rtciobg" }, 106 { .compatible = "sirf,prima2-rtciobg" },
107 { .compatible = "sirf,marco-rtciobg" },
107 {} 108 {}
108}; 109};
109 110
diff --git a/arch/arm/mach-prima2/timer-marco.c b/arch/arm/mach-prima2/timer-marco.c
new file mode 100644
index 000000000000..f4eea2e97eb0
--- /dev/null
+++ b/arch/arm/mach-prima2/timer-marco.c
@@ -0,0 +1,316 @@
1/*
2 * System timer for CSR SiRFprimaII
3 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/kernel.h>
10#include <linux/interrupt.h>
11#include <linux/clockchips.h>
12#include <linux/clocksource.h>
13#include <linux/bitops.h>
14#include <linux/irq.h>
15#include <linux/clk.h>
16#include <linux/slab.h>
17#include <linux/of.h>
18#include <linux/of_irq.h>
19#include <linux/of_address.h>
20#include <asm/sched_clock.h>
21#include <asm/localtimer.h>
22#include <asm/mach/time.h>
23
24#include "common.h"
25
26#define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000
27#define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004
28#define SIRFSOC_TIMER_MATCH_0 0x0018
29#define SIRFSOC_TIMER_MATCH_1 0x001c
30#define SIRFSOC_TIMER_COUNTER_0 0x0048
31#define SIRFSOC_TIMER_COUNTER_1 0x004c
32#define SIRFSOC_TIMER_INTR_STATUS 0x0060
33#define SIRFSOC_TIMER_WATCHDOG_EN 0x0064
34#define SIRFSOC_TIMER_64COUNTER_CTRL 0x0068
35#define SIRFSOC_TIMER_64COUNTER_LO 0x006c
36#define SIRFSOC_TIMER_64COUNTER_HI 0x0070
37#define SIRFSOC_TIMER_64COUNTER_LOAD_LO 0x0074
38#define SIRFSOC_TIMER_64COUNTER_LOAD_HI 0x0078
39#define SIRFSOC_TIMER_64COUNTER_RLATCHED_LO 0x007c
40#define SIRFSOC_TIMER_64COUNTER_RLATCHED_HI 0x0080
41
42#define SIRFSOC_TIMER_REG_CNT 6
43
44static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
45 SIRFSOC_TIMER_WATCHDOG_EN,
46 SIRFSOC_TIMER_32COUNTER_0_CTRL,
47 SIRFSOC_TIMER_32COUNTER_1_CTRL,
48 SIRFSOC_TIMER_64COUNTER_CTRL,
49 SIRFSOC_TIMER_64COUNTER_RLATCHED_LO,
50 SIRFSOC_TIMER_64COUNTER_RLATCHED_HI,
51};
52
53static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT];
54
55static void __iomem *sirfsoc_timer_base;
56static void __init sirfsoc_of_timer_map(void);
57
58/* disable count and interrupt */
59static inline void sirfsoc_timer_count_disable(int idx)
60{
61 writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx) & ~0x7,
62 sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx);
63}
64
65/* enable count and interrupt */
66static inline void sirfsoc_timer_count_enable(int idx)
67{
68 writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx) | 0x7,
69 sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx);
70}
71
72/* timer interrupt handler */
73static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
74{
75 struct clock_event_device *ce = dev_id;
76 int cpu = smp_processor_id();
77
78 /* clear timer interrupt */
79 writel_relaxed(BIT(cpu), sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
80
81 if (ce->mode == CLOCK_EVT_MODE_ONESHOT)
82 sirfsoc_timer_count_disable(cpu);
83
84 ce->event_handler(ce);
85
86 return IRQ_HANDLED;
87}
88
89/* read 64-bit timer counter */
90static cycle_t sirfsoc_timer_read(struct clocksource *cs)
91{
92 u64 cycles;
93
94 writel_relaxed((readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) |
95 BIT(0)) & ~BIT(1), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
96
97 cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_RLATCHED_HI);
98 cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_RLATCHED_LO);
99
100 return cycles;
101}
102
103static int sirfsoc_timer_set_next_event(unsigned long delta,
104 struct clock_event_device *ce)
105{
106 int cpu = smp_processor_id();
107
108 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_0 +
109 4 * cpu);
110 writel_relaxed(delta, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0 +
111 4 * cpu);
112
113 /* enable the tick */
114 sirfsoc_timer_count_enable(cpu);
115
116 return 0;
117}
118
119static void sirfsoc_timer_set_mode(enum clock_event_mode mode,
120 struct clock_event_device *ce)
121{
122 switch (mode) {
123 case CLOCK_EVT_MODE_ONESHOT:
124 /* enable in set_next_event */
125 break;
126 default:
127 break;
128 }
129
130 sirfsoc_timer_count_disable(smp_processor_id());
131}
132
133static void sirfsoc_clocksource_suspend(struct clocksource *cs)
134{
135 int i;
136
137 for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++)
138 sirfsoc_timer_reg_val[i] = readl_relaxed(sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
139}
140
141static void sirfsoc_clocksource_resume(struct clocksource *cs)
142{
143 int i;
144
145 for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++)
146 writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
147
148 writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2],
149 sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO);
150 writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1],
151 sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_HI);
152
153 writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) |
154 BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
155}
156
157static struct clock_event_device sirfsoc_clockevent = {
158 .name = "sirfsoc_clockevent",
159 .rating = 200,
160 .features = CLOCK_EVT_FEAT_ONESHOT,
161 .set_mode = sirfsoc_timer_set_mode,
162 .set_next_event = sirfsoc_timer_set_next_event,
163};
164
165static struct clocksource sirfsoc_clocksource = {
166 .name = "sirfsoc_clocksource",
167 .rating = 200,
168 .mask = CLOCKSOURCE_MASK(64),
169 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
170 .read = sirfsoc_timer_read,
171 .suspend = sirfsoc_clocksource_suspend,
172 .resume = sirfsoc_clocksource_resume,
173};
174
175static struct irqaction sirfsoc_timer_irq = {
176 .name = "sirfsoc_timer0",
177 .flags = IRQF_TIMER | IRQF_NOBALANCING,
178 .handler = sirfsoc_timer_interrupt,
179 .dev_id = &sirfsoc_clockevent,
180};
181
182#ifdef CONFIG_LOCAL_TIMERS
183
184static struct irqaction sirfsoc_timer1_irq = {
185 .name = "sirfsoc_timer1",
186 .flags = IRQF_TIMER | IRQF_NOBALANCING,
187 .handler = sirfsoc_timer_interrupt,
188};
189
190static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce)
191{
192 /* Use existing clock_event for cpu 0 */
193 if (!smp_processor_id())
194 return 0;
195
196 ce->irq = sirfsoc_timer1_irq.irq;
197 ce->name = "local_timer";
198 ce->features = sirfsoc_clockevent.features;
199 ce->rating = sirfsoc_clockevent.rating;
200 ce->set_mode = sirfsoc_timer_set_mode;
201 ce->set_next_event = sirfsoc_timer_set_next_event;
202 ce->shift = sirfsoc_clockevent.shift;
203 ce->mult = sirfsoc_clockevent.mult;
204 ce->max_delta_ns = sirfsoc_clockevent.max_delta_ns;
205 ce->min_delta_ns = sirfsoc_clockevent.min_delta_ns;
206
207 sirfsoc_timer1_irq.dev_id = ce;
208 BUG_ON(setup_irq(ce->irq, &sirfsoc_timer1_irq));
209 irq_set_affinity(sirfsoc_timer1_irq.irq, cpumask_of(1));
210
211 clockevents_register_device(ce);
212 return 0;
213}
214
215static void sirfsoc_local_timer_stop(struct clock_event_device *ce)
216{
217 sirfsoc_timer_count_disable(1);
218
219 remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq);
220}
221
222static struct local_timer_ops sirfsoc_local_timer_ops __cpuinitdata = {
223 .setup = sirfsoc_local_timer_setup,
224 .stop = sirfsoc_local_timer_stop,
225};
226#endif /* CONFIG_LOCAL_TIMERS */
227
228static void __init sirfsoc_clockevent_init(void)
229{
230 clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60);
231
232 sirfsoc_clockevent.max_delta_ns =
233 clockevent_delta2ns(-2, &sirfsoc_clockevent);
234 sirfsoc_clockevent.min_delta_ns =
235 clockevent_delta2ns(2, &sirfsoc_clockevent);
236
237 sirfsoc_clockevent.cpumask = cpumask_of(0);
238 clockevents_register_device(&sirfsoc_clockevent);
239#ifdef CONFIG_LOCAL_TIMERS
240 local_timer_register(&sirfsoc_local_timer_ops);
241#endif
242}
243
244/* initialize the kernel jiffy timer source */
245void __init sirfsoc_marco_timer_init(void)
246{
247 unsigned long rate;
248 u32 timer_div;
249 struct clk *clk;
250
251 /* initialize clocking early, we want to set the OS timer */
252 sirfsoc_of_clk_init();
253
254 /* timer's input clock is io clock */
255 clk = clk_get_sys("io", NULL);
256
257 BUG_ON(IS_ERR(clk));
258 rate = clk_get_rate(clk);
259
260 BUG_ON(rate < CLOCK_TICK_RATE);
261 BUG_ON(rate % CLOCK_TICK_RATE);
262
263 sirfsoc_of_timer_map();
264
265 /* Initialize the timer dividers */
266 timer_div = rate / CLOCK_TICK_RATE - 1;
267 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
268 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL);
269 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);
270
271 /* Initialize timer counters to 0 */
272 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO);
273 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_HI);
274 writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) |
275 BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
276 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_0);
277 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_1);
278
279 /* Clear all interrupts */
280 writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
281
282 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
283
284 BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
285
286 sirfsoc_clockevent_init();
287}
288
289static struct of_device_id timer_ids[] = {
290 { .compatible = "sirf,marco-tick" },
291 {},
292};
293
294static void __init sirfsoc_of_timer_map(void)
295{
296 struct device_node *np;
297
298 np = of_find_matching_node(NULL, timer_ids);
299 if (!np)
300 return;
301 sirfsoc_timer_base = of_iomap(np, 0);
302 if (!sirfsoc_timer_base)
303 panic("unable to map timer cpu registers\n");
304
305 sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0);
306 if (!sirfsoc_timer_irq.irq)
307 panic("No irq passed for timer0 via DT\n");
308
309#ifdef CONFIG_LOCAL_TIMERS
310 sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1);
311 if (!sirfsoc_timer1_irq.irq)
312 panic("No irq passed for timer1 via DT\n");
313#endif
314
315 of_node_put(np);
316}
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer-prima2.c
index a7a2c199c3ea..6da584f8a949 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer-prima2.c
@@ -181,7 +181,7 @@ static void __init sirfsoc_clockevent_init(void)
181} 181}
182 182
183/* initialize the kernel jiffy timer source */ 183/* initialize the kernel jiffy timer source */
184void __init sirfsoc_timer_init(void) 184void __init sirfsoc_prima2_timer_init(void)
185{ 185{
186 unsigned long rate; 186 unsigned long rate;
187 struct clk *clk; 187 struct clk *clk;
@@ -220,14 +220,14 @@ static struct of_device_id timer_ids[] = {
220 {}, 220 {},
221}; 221};
222 222
223void __init sirfsoc_of_timer_map(void) 223static void __init sirfsoc_of_timer_map(void)
224{ 224{
225 struct device_node *np; 225 struct device_node *np;
226 const unsigned int *intspec; 226 const unsigned int *intspec;
227 227
228 np = of_find_matching_node(NULL, timer_ids); 228 np = of_find_matching_node(NULL, timer_ids);
229 if (!np) 229 if (!np)
230 panic("unable to find compatible timer node in dtb\n"); 230 return;
231 sirfsoc_timer_base = of_iomap(np, 0); 231 sirfsoc_timer_base = of_iomap(np, 0);
232 if (!sirfsoc_timer_base) 232 if (!sirfsoc_timer_base)
233 panic("unable to map timer cpu registers\n"); 233 panic("unable to map timer cpu registers\n");
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index a1e931337d41..e1fac57514b9 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o clock-emev2.o
15# SMP objects 15# SMP objects
16smp-y := platsmp.o headsmp.o 16smp-y := platsmp.o headsmp.o
17smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o 17smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
18smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o 18smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-sh73a0.o
19smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o 19smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o
20smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o 20smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o
21 21
@@ -30,6 +30,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o
30obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o 30obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
31obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o 31obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o
32obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o 32obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o
33obj-$(CONFIG_ARCH_SH73A0) += pm-sh73a0.o
33 34
34# Board objects 35# Board objects
35obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o 36obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
index 6bcf3cbd9223..81d91fda2d90 100644
--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -1181,6 +1181,8 @@ static void __init eva_init(void)
1181 rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device); 1181 rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device);
1182 if (usb) 1182 if (usb)
1183 rmobile_add_device_to_domain("A3SP", usb); 1183 rmobile_add_device_to_domain("A3SP", usb);
1184
1185 r8a7740_pm_init();
1184} 1186}
1185 1187
1186static void __init eva_earlytimer_init(void) 1188static void __init eva_earlytimer_init(void)
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index 5394d804a716..3efff2e7b1e7 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -772,6 +772,8 @@ static void __init kzm_init(void)
772 772
773 sh73a0_add_standard_devices(); 773 sh73a0_add_standard_devices();
774 platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices)); 774 platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices));
775
776 sh73a0_pm_init();
775} 777}
776 778
777static void kzm9g_restart(char mode, const char *cmd) 779static void kzm9g_restart(char mode, const char *cmd)
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index eac49d59782f..19ce885a3b43 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -581,10 +581,14 @@ static struct clk_lookup lookups[] = {
581 581
582 /* MSTP32 clocks */ 582 /* MSTP32 clocks */
583 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), 583 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]),
584 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP111]), 584 CLKDEV_DEV_ID("sh_tmu.3", &mstp_clks[MSTP111]),
585 CLKDEV_DEV_ID("sh_tmu.4", &mstp_clks[MSTP111]),
586 CLKDEV_DEV_ID("sh_tmu.5", &mstp_clks[MSTP111]),
585 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), 587 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
586 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), 588 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]),
587 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), 589 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]),
590 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]),
591 CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP125]),
588 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), 592 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]),
589 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), 593 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]),
590 594
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index c019609da660..1db36537255c 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -162,6 +162,7 @@ static struct clk_lookup lookups[] = {
162 CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ 162 CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
163 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */ 163 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
164 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */ 164 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
165 CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP016]), /* TMU02 */
165 CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ 166 CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
166 CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */ 167 CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
167 CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */ 168 CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 3ca6757b129a..45d21fe317f4 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -544,6 +544,7 @@ static struct clk_lookup lookups[] = {
544 544
545 /* MSTP32 clocks */ 545 /* MSTP32 clocks */
546 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ 546 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
547 CLKDEV_DEV_ID("fff30000.i2c", &mstp_clks[MSTP001]), /* IIC2 */
547 CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */ 548 CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
548 CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ 549 CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
549 CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ 550 CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
@@ -556,6 +557,7 @@ static struct clk_lookup lookups[] = {
556 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */ 557 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
557 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ 558 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
558 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ 559 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
560 CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]), /* IIC0 */
559 CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */ 561 CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
560 CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ 562 CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
561 CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ 563 CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
@@ -577,18 +579,25 @@ static struct clk_lookup lookups[] = {
577 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ 579 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
578 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ 580 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
579 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ 581 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
582 CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]), /* IIC1 */
580 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ 583 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
581 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */ 584 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
582 CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */ 585 CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
583 CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */ 586 CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */
584 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ 587 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
588 CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
585 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ 589 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
590 CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
586 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ 591 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
592 CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMC */
587 CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */ 593 CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
588 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */ 594 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
595 CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), /* SDHI2 */
589 CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ 596 CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
590 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ 597 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
598 CLKDEV_DEV_ID("e6d20000.i2c", &mstp_clks[MSTP411]), /* IIC3 */
591 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ 599 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
600 CLKDEV_DEV_ID("e6d30000.i2c", &mstp_clks[MSTP410]), /* IIC4 */
592 CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */ 601 CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
593 CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ 602 CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
594 CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ 603 CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 516ff7f3e434..afa5423a0f93 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -264,17 +264,17 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
264 SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags) 264 SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
265 265
266static struct clk div4_clks[DIV4_NR] = { 266static struct clk div4_clks[DIV4_NR] = {
267 [DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT), 267 [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
268 [DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT), 268 [DIV4_ZG] = DIV4(FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
269 [DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT), 269 [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
270 [DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT), 270 [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
271 [DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0), 271 [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0),
272 [DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0), 272 [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0),
273 [DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0), 273 [DIV4_Z] = DIV4(FRQCRB, 24, 0x97f, 0),
274 [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0), 274 [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xdff, 0),
275 [DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0), 275 [DIV4_ZT] = DIV4(FRQCRB, 16, 0xdff, 0),
276 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0), 276 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
277 [DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0), 277 [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
278}; 278};
279 279
280enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, 280enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
@@ -525,6 +525,13 @@ static struct clk mstp_clks[MSTP_NR] = {
525 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ 525 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
526}; 526};
527 527
528/* The lookups structure below includes duplicate entries for some clocks
529 * with alternate names.
530 * - The traditional name used when a device is initialised with platform data
531 * - The name used when a device is initialised using device tree
532 * The longer-term aim is to remove these duplicates, and indeed the
533 * lookups table entirely, by describing clocks using device tree.
534 */
528static struct clk_lookup lookups[] = { 535static struct clk_lookup lookups[] = {
529 /* main clocks */ 536 /* main clocks */
530 CLKDEV_CON_ID("r_clk", &r_clk), 537 CLKDEV_CON_ID("r_clk", &r_clk),
@@ -545,6 +552,7 @@ static struct clk_lookup lookups[] = {
545 552
546 /* MSTP32 clocks */ 553 /* MSTP32 clocks */
547 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */ 554 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
555 CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
548 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */ 556 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
549 CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */ 557 CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
550 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */ 558 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
@@ -553,6 +561,7 @@ static struct clk_lookup lookups[] = {
553 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ 561 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
554 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ 562 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
555 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ 563 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
564 CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
556 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ 565 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
557 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ 566 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
558 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ 567 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
@@ -569,17 +578,21 @@ static struct clk_lookup lookups[] = {
569 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */ 578 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
570 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ 579 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
571 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ 580 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
581 CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
572 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */ 582 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
573 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ 583 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
574 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ 584 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
575 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ 585 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
586 CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
576 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ 587 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
577 CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */ 588 CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
578 CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */ 589 CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
579 CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */ 590 CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
580 CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */ 591 CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
581 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */ 592 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
593 CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
582 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */ 594 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
595 CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
583 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ 596 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
584}; 597};
585 598
diff --git a/arch/arm/mach-shmobile/headsmp-sh73a0.S b/arch/arm/mach-shmobile/headsmp-sh73a0.S
new file mode 100644
index 000000000000..bec4c0d9b713
--- /dev/null
+++ b/arch/arm/mach-shmobile/headsmp-sh73a0.S
@@ -0,0 +1,50 @@
1/*
2 * SMP support for SoC sh73a0
3 *
4 * Copyright (C) 2012 Bastian Hecht
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#include <linux/linkage.h>
23#include <linux/init.h>
24#include <asm/memory.h>
25
26 __CPUINIT
27/*
28 * Reset vector for secondary CPUs.
29 *
30 * First we turn on L1 cache coherency for our CPU. Then we jump to
31 * shmobile_invalidate_start that invalidates the cache and hands over control
32 * to the common ARM startup code.
33 * This function will be mapped to address 0 by the SBAR register.
34 * A normal branch is out of range here so we need a long jump. We jump to
35 * the physical address as the MMU is still turned off.
36 */
37 .align 12
38ENTRY(sh73a0_secondary_vector)
39 mrc p15, 0, r0, c0, c0, 5 @ read MIPDR
40 and r0, r0, #3 @ mask out cpu ID
41 lsl r0, r0, #3 @ we will shift by cpu_id * 8 bits
42 mov r1, #0xf0000000 @ SCU base address
43 ldr r2, [r1, #8] @ SCU Power Status Register
44 mov r3, #3
45 bic r2, r2, r3, lsl r0 @ Clear bits of our CPU (Run Mode)
46 str r2, [r1, #8] @ write back
47
48 ldr pc, 1f
491: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET
50ENDPROC(sh73a0_secondary_vector)
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
index b202c1272526..96001fd49b6c 100644
--- a/arch/arm/mach-shmobile/headsmp.S
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -16,54 +16,6 @@
16 16
17 __CPUINIT 17 __CPUINIT
18 18
19/* Cache invalidation nicked from arch/arm/mach-imx/head-v7.S, thanks!
20 *
21 * The secondary kernel init calls v7_flush_dcache_all before it enables
22 * the L1; however, the L1 comes out of reset in an undefined state, so
23 * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
24 * of cache lines with uninitialized data and uninitialized tags to get
25 * written out to memory, which does really unpleasant things to the main
26 * processor. We fix this by performing an invalidate, rather than a
27 * clean + invalidate, before jumping into the kernel.
28 *
29 * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
30 * to be called for both secondary cores startup and primary core resume
31 * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
32 */
33ENTRY(v7_invalidate_l1)
34 mov r0, #0
35 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
36 mcr p15, 2, r0, c0, c0, 0
37 mrc p15, 1, r0, c0, c0, 0
38
39 ldr r1, =0x7fff
40 and r2, r1, r0, lsr #13
41
42 ldr r1, =0x3ff
43
44 and r3, r1, r0, lsr #3 @ NumWays - 1
45 add r2, r2, #1 @ NumSets
46
47 and r0, r0, #0x7
48 add r0, r0, #4 @ SetShift
49
50 clz r1, r3 @ WayShift
51 add r4, r3, #1 @ NumWays
521: sub r2, r2, #1 @ NumSets--
53 mov r3, r4 @ Temp = NumWays
542: subs r3, r3, #1 @ Temp--
55 mov r5, r3, lsl r1
56 mov r6, r2, lsl r0
57 orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
58 mcr p15, 0, r5, c7, c6, 2
59 bgt 2b
60 cmp r2, #0
61 bgt 1b
62 dsb
63 isb
64 mov pc, lr
65ENDPROC(v7_invalidate_l1)
66
67ENTRY(shmobile_invalidate_start) 19ENTRY(shmobile_invalidate_start)
68 bl v7_invalidate_l1 20 bl v7_invalidate_l1
69 b secondary_startup 21 b secondary_startup
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
index b09a0bdbf813..a1524e3367b0 100644
--- a/arch/arm/mach-shmobile/hotplug.c
+++ b/arch/arm/mach-shmobile/hotplug.c
@@ -56,6 +56,12 @@ int shmobile_cpu_disable(unsigned int cpu)
56 return cpu == 0 ? -EPERM : 0; 56 return cpu == 0 ? -EPERM : 0;
57} 57}
58 58
59int shmobile_cpu_disable_any(unsigned int cpu)
60{
61 cpumask_clear_cpu(cpu, &dead_cpus);
62 return 0;
63}
64
59int shmobile_cpu_is_dead(unsigned int cpu) 65int shmobile_cpu_is_dead(unsigned int cpu)
60{ 66{
61 return cpumask_test_cpu(cpu, &dead_cpus); 67 return cpumask_test_cpu(cpu, &dead_cpus);
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index a57439eec11a..e48606d8a2be 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -23,6 +23,8 @@ extern void sh7372_map_io(void);
23extern void sh7372_earlytimer_init(void); 23extern void sh7372_earlytimer_init(void);
24extern void sh7372_add_early_devices(void); 24extern void sh7372_add_early_devices(void);
25extern void sh7372_add_standard_devices(void); 25extern void sh7372_add_standard_devices(void);
26extern void sh7372_add_early_devices_dt(void);
27extern void sh7372_add_standard_devices_dt(void);
26extern void sh7372_clock_init(void); 28extern void sh7372_clock_init(void);
27extern void sh7372_pinmux_init(void); 29extern void sh7372_pinmux_init(void);
28extern void sh7372_pm_init(void); 30extern void sh7372_pm_init(void);
@@ -32,12 +34,17 @@ extern struct clk sh7372_extal1_clk;
32extern struct clk sh7372_extal2_clk; 34extern struct clk sh7372_extal2_clk;
33 35
34extern void sh73a0_init_irq(void); 36extern void sh73a0_init_irq(void);
37extern void sh73a0_init_irq_dt(void);
35extern void sh73a0_map_io(void); 38extern void sh73a0_map_io(void);
36extern void sh73a0_earlytimer_init(void); 39extern void sh73a0_earlytimer_init(void);
37extern void sh73a0_add_early_devices(void); 40extern void sh73a0_add_early_devices(void);
41extern void sh73a0_add_early_devices_dt(void);
38extern void sh73a0_add_standard_devices(void); 42extern void sh73a0_add_standard_devices(void);
43extern void sh73a0_add_standard_devices_dt(void);
39extern void sh73a0_clock_init(void); 44extern void sh73a0_clock_init(void);
40extern void sh73a0_pinmux_init(void); 45extern void sh73a0_pinmux_init(void);
46extern void sh73a0_pm_init(void);
47extern void sh73a0_secondary_vector(void);
41extern struct clk sh73a0_extal1_clk; 48extern struct clk sh73a0_extal1_clk;
42extern struct clk sh73a0_extal2_clk; 49extern struct clk sh73a0_extal2_clk;
43extern struct clk sh73a0_extcki_clk; 50extern struct clk sh73a0_extcki_clk;
@@ -49,6 +56,7 @@ extern void r8a7740_add_early_devices(void);
49extern void r8a7740_add_standard_devices(void); 56extern void r8a7740_add_standard_devices(void);
50extern void r8a7740_clock_init(u8 md_ck); 57extern void r8a7740_clock_init(u8 md_ck);
51extern void r8a7740_pinmux_init(void); 58extern void r8a7740_pinmux_init(void);
59extern void r8a7740_pm_init(void);
52 60
53extern void r8a7779_init_irq(void); 61extern void r8a7779_init_irq(void);
54extern void r8a7779_map_io(void); 62extern void r8a7779_map_io(void);
@@ -76,6 +84,7 @@ static inline int shmobile_cpuidle_init(void) { return 0; }
76 84
77extern void shmobile_cpu_die(unsigned int cpu); 85extern void shmobile_cpu_die(unsigned int cpu);
78extern int shmobile_cpu_disable(unsigned int cpu); 86extern int shmobile_cpu_disable(unsigned int cpu);
87extern int shmobile_cpu_disable_any(unsigned int cpu);
79 88
80#ifdef CONFIG_HOTPLUG_CPU 89#ifdef CONFIG_HOTPLUG_CPU
81extern int shmobile_cpu_is_dead(unsigned int cpu); 90extern int shmobile_cpu_is_dead(unsigned int cpu);
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
index 978369973be4..91faba666d46 100644
--- a/arch/arm/mach-shmobile/intc-sh73a0.c
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -23,6 +23,7 @@
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/sh_intc.h> 25#include <linux/sh_intc.h>
26#include <linux/irqchip.h>
26#include <linux/irqchip/arm-gic.h> 27#include <linux/irqchip/arm-gic.h>
27#include <mach/intc.h> 28#include <mach/intc.h>
28#include <mach/irqs.h> 29#include <mach/irqs.h>
@@ -315,11 +316,6 @@ static int intca_gic_set_type(struct irq_data *data, unsigned int type)
315 return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type); 316 return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type);
316} 317}
317 318
318static int intca_gic_set_wake(struct irq_data *data, unsigned int on)
319{
320 return irq_cbp(irq_set_wake, to_intca_reloc_irq(data), on);
321}
322
323#ifdef CONFIG_SMP 319#ifdef CONFIG_SMP
324static int intca_gic_set_affinity(struct irq_data *data, 320static int intca_gic_set_affinity(struct irq_data *data,
325 const struct cpumask *cpumask, 321 const struct cpumask *cpumask,
@@ -339,7 +335,7 @@ struct irq_chip intca_gic_irq_chip = {
339 .irq_disable = intca_gic_disable, 335 .irq_disable = intca_gic_disable,
340 .irq_shutdown = intca_gic_disable, 336 .irq_shutdown = intca_gic_disable,
341 .irq_set_type = intca_gic_set_type, 337 .irq_set_type = intca_gic_set_type,
342 .irq_set_wake = intca_gic_set_wake, 338 .irq_set_wake = sh73a0_set_wake,
343#ifdef CONFIG_SMP 339#ifdef CONFIG_SMP
344 .irq_set_affinity = intca_gic_set_affinity, 340 .irq_set_affinity = intca_gic_set_affinity,
345#endif 341#endif
@@ -464,3 +460,11 @@ void __init sh73a0_init_irq(void)
464 sh73a0_pint1_cascade.handler = sh73a0_pint1_demux; 460 sh73a0_pint1_cascade.handler = sh73a0_pint1_demux;
465 setup_irq(gic_spi(34), &sh73a0_pint1_cascade); 461 setup_irq(gic_spi(34), &sh73a0_pint1_cascade);
466} 462}
463
464#ifdef CONFIG_OF
465void __init sh73a0_init_irq_dt(void)
466{
467 irqchip_init();
468 gic_arch_extn.irq_set_wake = sh73a0_set_wake;
469}
470#endif
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
index 21e5316d2d88..40b87aa1d448 100644
--- a/arch/arm/mach-shmobile/pm-r8a7740.c
+++ b/arch/arm/mach-shmobile/pm-r8a7740.c
@@ -9,7 +9,9 @@
9 * for more details. 9 * for more details.
10 */ 10 */
11#include <linux/console.h> 11#include <linux/console.h>
12#include <linux/suspend.h>
12#include <mach/pm-rmobile.h> 13#include <mach/pm-rmobile.h>
14#include <mach/common.h>
13 15
14#ifdef CONFIG_PM 16#ifdef CONFIG_PM
15static int r8a7740_pd_a4s_suspend(void) 17static int r8a7740_pd_a4s_suspend(void)
@@ -58,3 +60,23 @@ void __init r8a7740_init_pm_domains(void)
58} 60}
59 61
60#endif /* CONFIG_PM */ 62#endif /* CONFIG_PM */
63
64#ifdef CONFIG_SUSPEND
65static int r8a7740_enter_suspend(suspend_state_t suspend_state)
66{
67 cpu_do_idle();
68 return 0;
69}
70
71static void r8a7740_suspend_init(void)
72{
73 shmobile_suspend_ops.enter = r8a7740_enter_suspend;
74}
75#else
76static void r8a7740_suspend_init(void) {}
77#endif
78
79void __init r8a7740_pm_init(void)
80{
81 r8a7740_suspend_init();
82}
diff --git a/arch/arm/mach-shmobile/pm-sh73a0.c b/arch/arm/mach-shmobile/pm-sh73a0.c
new file mode 100644
index 000000000000..99086e98fbbc
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-sh73a0.c
@@ -0,0 +1,32 @@
1/*
2 * sh73a0 Power management support
3 *
4 * Copyright (C) 2012 Bastian Hecht <hechtb+renesas@gmail.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/suspend.h>
12#include <mach/common.h>
13
14#ifdef CONFIG_SUSPEND
15static int sh73a0_enter_suspend(suspend_state_t suspend_state)
16{
17 cpu_do_idle();
18 return 0;
19}
20
21static void sh73a0_suspend_init(void)
22{
23 shmobile_suspend_ops.enter = sh73a0_enter_suspend;
24}
25#else
26static void sh73a0_suspend_init(void) {}
27#endif
28
29void __init sh73a0_pm_init(void)
30{
31 sh73a0_suspend_init();
32}
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index b580979923eb..30ac79c7c687 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -27,7 +27,6 @@
27#include <linux/serial_sci.h> 27#include <linux/serial_sci.h>
28#include <linux/sh_dma.h> 28#include <linux/sh_dma.h>
29#include <linux/sh_timer.h> 29#include <linux/sh_timer.h>
30#include <linux/dma-mapping.h>
31#include <mach/dma-register.h> 30#include <mach/dma-register.h>
32#include <mach/r8a7740.h> 31#include <mach/r8a7740.h>
33#include <mach/pm-rmobile.h> 32#include <mach/pm-rmobile.h>
@@ -288,6 +287,97 @@ static struct platform_device cmt10_device = {
288 .num_resources = ARRAY_SIZE(cmt10_resources), 287 .num_resources = ARRAY_SIZE(cmt10_resources),
289}; 288};
290 289
290/* TMU */
291static struct sh_timer_config tmu00_platform_data = {
292 .name = "TMU00",
293 .channel_offset = 0x4,
294 .timer_bit = 0,
295 .clockevent_rating = 200,
296};
297
298static struct resource tmu00_resources[] = {
299 [0] = {
300 .name = "TMU00",
301 .start = 0xfff80008,
302 .end = 0xfff80014 - 1,
303 .flags = IORESOURCE_MEM,
304 },
305 [1] = {
306 .start = intcs_evt2irq(0xe80),
307 .flags = IORESOURCE_IRQ,
308 },
309};
310
311static struct platform_device tmu00_device = {
312 .name = "sh_tmu",
313 .id = 0,
314 .dev = {
315 .platform_data = &tmu00_platform_data,
316 },
317 .resource = tmu00_resources,
318 .num_resources = ARRAY_SIZE(tmu00_resources),
319};
320
321static struct sh_timer_config tmu01_platform_data = {
322 .name = "TMU01",
323 .channel_offset = 0x10,
324 .timer_bit = 1,
325 .clocksource_rating = 200,
326};
327
328static struct resource tmu01_resources[] = {
329 [0] = {
330 .name = "TMU01",
331 .start = 0xfff80014,
332 .end = 0xfff80020 - 1,
333 .flags = IORESOURCE_MEM,
334 },
335 [1] = {
336 .start = intcs_evt2irq(0xea0),
337 .flags = IORESOURCE_IRQ,
338 },
339};
340
341static struct platform_device tmu01_device = {
342 .name = "sh_tmu",
343 .id = 1,
344 .dev = {
345 .platform_data = &tmu01_platform_data,
346 },
347 .resource = tmu01_resources,
348 .num_resources = ARRAY_SIZE(tmu01_resources),
349};
350
351static struct sh_timer_config tmu02_platform_data = {
352 .name = "TMU02",
353 .channel_offset = 0x1C,
354 .timer_bit = 2,
355 .clocksource_rating = 200,
356};
357
358static struct resource tmu02_resources[] = {
359 [0] = {
360 .name = "TMU02",
361 .start = 0xfff80020,
362 .end = 0xfff8002C - 1,
363 .flags = IORESOURCE_MEM,
364 },
365 [1] = {
366 .start = intcs_evt2irq(0xec0),
367 .flags = IORESOURCE_IRQ,
368 },
369};
370
371static struct platform_device tmu02_device = {
372 .name = "sh_tmu",
373 .id = 2,
374 .dev = {
375 .platform_data = &tmu02_platform_data,
376 },
377 .resource = tmu02_resources,
378 .num_resources = ARRAY_SIZE(tmu02_resources),
379};
380
291static struct platform_device *r8a7740_early_devices[] __initdata = { 381static struct platform_device *r8a7740_early_devices[] __initdata = {
292 &scif0_device, 382 &scif0_device,
293 &scif1_device, 383 &scif1_device,
@@ -299,6 +389,9 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
299 &scif7_device, 389 &scif7_device,
300 &scifb_device, 390 &scifb_device,
301 &cmt10_device, 391 &cmt10_device,
392 &tmu00_device,
393 &tmu01_device,
394 &tmu02_device,
302}; 395};
303 396
304/* DMA */ 397/* DMA */
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 344eb79658f9..c54ff9b29fe5 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -91,8 +91,7 @@ static struct plat_sci_port scif0_platform_data = {
91 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 91 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
92 .scbrr_algo_id = SCBRR_ALGO_2, 92 .scbrr_algo_id = SCBRR_ALGO_2,
93 .type = PORT_SCIF, 93 .type = PORT_SCIF,
94 .irqs = { gic_spi(88), gic_spi(88), 94 .irqs = SCIx_IRQ_MUXED(gic_spi(88)),
95 gic_spi(88), gic_spi(88) },
96}; 95};
97 96
98static struct platform_device scif0_device = { 97static struct platform_device scif0_device = {
@@ -109,8 +108,7 @@ static struct plat_sci_port scif1_platform_data = {
109 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 108 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
110 .scbrr_algo_id = SCBRR_ALGO_2, 109 .scbrr_algo_id = SCBRR_ALGO_2,
111 .type = PORT_SCIF, 110 .type = PORT_SCIF,
112 .irqs = { gic_spi(89), gic_spi(89), 111 .irqs = SCIx_IRQ_MUXED(gic_spi(89)),
113 gic_spi(89), gic_spi(89) },
114}; 112};
115 113
116static struct platform_device scif1_device = { 114static struct platform_device scif1_device = {
@@ -127,8 +125,7 @@ static struct plat_sci_port scif2_platform_data = {
127 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 125 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
128 .scbrr_algo_id = SCBRR_ALGO_2, 126 .scbrr_algo_id = SCBRR_ALGO_2,
129 .type = PORT_SCIF, 127 .type = PORT_SCIF,
130 .irqs = { gic_spi(90), gic_spi(90), 128 .irqs = SCIx_IRQ_MUXED(gic_spi(90)),
131 gic_spi(90), gic_spi(90) },
132}; 129};
133 130
134static struct platform_device scif2_device = { 131static struct platform_device scif2_device = {
@@ -145,8 +142,7 @@ static struct plat_sci_port scif3_platform_data = {
145 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 142 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
146 .scbrr_algo_id = SCBRR_ALGO_2, 143 .scbrr_algo_id = SCBRR_ALGO_2,
147 .type = PORT_SCIF, 144 .type = PORT_SCIF,
148 .irqs = { gic_spi(91), gic_spi(91), 145 .irqs = SCIx_IRQ_MUXED(gic_spi(91)),
149 gic_spi(91), gic_spi(91) },
150}; 146};
151 147
152static struct platform_device scif3_device = { 148static struct platform_device scif3_device = {
@@ -163,8 +159,7 @@ static struct plat_sci_port scif4_platform_data = {
163 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 159 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
164 .scbrr_algo_id = SCBRR_ALGO_2, 160 .scbrr_algo_id = SCBRR_ALGO_2,
165 .type = PORT_SCIF, 161 .type = PORT_SCIF,
166 .irqs = { gic_spi(92), gic_spi(92), 162 .irqs = SCIx_IRQ_MUXED(gic_spi(92)),
167 gic_spi(92), gic_spi(92) },
168}; 163};
169 164
170static struct platform_device scif4_device = { 165static struct platform_device scif4_device = {
@@ -181,8 +176,7 @@ static struct plat_sci_port scif5_platform_data = {
181 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 176 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
182 .scbrr_algo_id = SCBRR_ALGO_2, 177 .scbrr_algo_id = SCBRR_ALGO_2,
183 .type = PORT_SCIF, 178 .type = PORT_SCIF,
184 .irqs = { gic_spi(93), gic_spi(93), 179 .irqs = SCIx_IRQ_MUXED(gic_spi(93)),
185 gic_spi(93), gic_spi(93) },
186}; 180};
187 181
188static struct platform_device scif5_device = { 182static struct platform_device scif5_device = {
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index 48f7f583647a..2ecd6681692f 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -23,6 +23,7 @@
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/of_platform.h>
26#include <linux/delay.h> 27#include <linux/delay.h>
27#include <linux/input.h> 28#include <linux/input.h>
28#include <linux/io.h> 29#include <linux/io.h>
@@ -779,7 +780,7 @@ static struct platform_device pmu_device = {
779 .resource = pmu_resources, 780 .resource = pmu_resources,
780}; 781};
781 782
782static struct platform_device *sh73a0_early_devices[] __initdata = { 783static struct platform_device *sh73a0_early_devices_dt[] __initdata = {
783 &scif0_device, 784 &scif0_device,
784 &scif1_device, 785 &scif1_device,
785 &scif2_device, 786 &scif2_device,
@@ -790,6 +791,9 @@ static struct platform_device *sh73a0_early_devices[] __initdata = {
790 &scif7_device, 791 &scif7_device,
791 &scif8_device, 792 &scif8_device,
792 &cmt10_device, 793 &cmt10_device,
794};
795
796static struct platform_device *sh73a0_early_devices[] __initdata = {
793 &tmu00_device, 797 &tmu00_device,
794 &tmu01_device, 798 &tmu01_device,
795}; 799};
@@ -812,6 +816,8 @@ void __init sh73a0_add_standard_devices(void)
812 /* Clear software reset bit on SY-DMAC module */ 816 /* Clear software reset bit on SY-DMAC module */
813 __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2); 817 __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
814 818
819 platform_add_devices(sh73a0_early_devices_dt,
820 ARRAY_SIZE(sh73a0_early_devices_dt));
815 platform_add_devices(sh73a0_early_devices, 821 platform_add_devices(sh73a0_early_devices,
816 ARRAY_SIZE(sh73a0_early_devices)); 822 ARRAY_SIZE(sh73a0_early_devices));
817 platform_add_devices(sh73a0_late_devices, 823 platform_add_devices(sh73a0_late_devices,
@@ -830,9 +836,63 @@ void __init sh73a0_earlytimer_init(void)
830 836
831void __init sh73a0_add_early_devices(void) 837void __init sh73a0_add_early_devices(void)
832{ 838{
839 early_platform_add_devices(sh73a0_early_devices_dt,
840 ARRAY_SIZE(sh73a0_early_devices_dt));
833 early_platform_add_devices(sh73a0_early_devices, 841 early_platform_add_devices(sh73a0_early_devices,
834 ARRAY_SIZE(sh73a0_early_devices)); 842 ARRAY_SIZE(sh73a0_early_devices));
835 843
836 /* setup early console here as well */ 844 /* setup early console here as well */
837 shmobile_setup_console(); 845 shmobile_setup_console();
838} 846}
847
848#ifdef CONFIG_USE_OF
849
850/* Please note that the clock initialisation shcheme used in
851 * sh73a0_add_early_devices_dt() and sh73a0_add_standard_devices_dt()
852 * does not work with SMP as there is a yet to be resolved lock-up in
853 * workqueue initialisation.
854 *
855 * CONFIG_SMP should be disabled when using this code.
856 */
857
858void __init sh73a0_add_early_devices_dt(void)
859{
860 shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
861
862 early_platform_add_devices(sh73a0_early_devices_dt,
863 ARRAY_SIZE(sh73a0_early_devices_dt));
864
865 /* setup early console here as well */
866 shmobile_setup_console();
867}
868
869static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = {
870 {},
871};
872
873void __init sh73a0_add_standard_devices_dt(void)
874{
875 /* clocks are setup late during boot in the case of DT */
876 sh73a0_clock_init();
877
878 platform_add_devices(sh73a0_early_devices_dt,
879 ARRAY_SIZE(sh73a0_early_devices_dt));
880 of_platform_populate(NULL, of_default_bus_match_table,
881 sh73a0_auxdata_lookup, NULL);
882}
883
884static const char *sh73a0_boards_compat_dt[] __initdata = {
885 "renesas,sh73a0",
886 NULL,
887};
888
889DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)")
890 .map_io = sh73a0_map_io,
891 .init_early = sh73a0_add_early_devices_dt,
892 .nr_irqs = NR_IRQS_LEGACY,
893 .init_irq = sh73a0_init_irq_dt,
894 .init_machine = sh73a0_add_standard_devices_dt,
895 .init_time = shmobile_timer_init,
896 .dt_compat = sh73a0_boards_compat_dt,
897MACHINE_END
898#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/sleep-sh7372.S b/arch/arm/mach-shmobile/sleep-sh7372.S
index 1d564674451d..a9df53b69ab8 100644
--- a/arch/arm/mach-shmobile/sleep-sh7372.S
+++ b/arch/arm/mach-shmobile/sleep-sh7372.S
@@ -59,17 +59,19 @@ sh7372_do_idle_sysc:
59 mcr p15, 0, r0, c1, c0, 0 59 mcr p15, 0, r0, c1, c0, 0
60 isb 60 isb
61 61
62 /*
63 * Clean and invalidate data cache again.
64 */
65 ldr r1, kernel_flush
66 blx r1
67
62 /* disable L2 cache in the aux control register */ 68 /* disable L2 cache in the aux control register */
63 mrc p15, 0, r10, c1, c0, 1 69 mrc p15, 0, r10, c1, c0, 1
64 bic r10, r10, #2 70 bic r10, r10, #2
65 mcr p15, 0, r10, c1, c0, 1 71 mcr p15, 0, r10, c1, c0, 1
72 isb
66 73
67 /* 74 /*
68 * Invalidate data cache again.
69 */
70 ldr r1, kernel_flush
71 blx r1
72 /*
73 * The kernel doesn't interwork: v7_flush_dcache_all in particluar will 75 * The kernel doesn't interwork: v7_flush_dcache_all in particluar will
74 * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. 76 * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
75 * This sequence switches back to ARM. Note that .align may insert a 77 * This sequence switches back to ARM. Note that .align may insert a
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index 5c5bcb595350..acb46a94ccdf 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -25,6 +25,7 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/irqchip/arm-gic.h> 26#include <linux/irqchip/arm-gic.h>
27#include <mach/common.h> 27#include <mach/common.h>
28#include <asm/cacheflush.h>
28#include <asm/smp_plat.h> 29#include <asm/smp_plat.h>
29#include <mach/sh73a0.h> 30#include <mach/sh73a0.h>
30#include <asm/smp_scu.h> 31#include <asm/smp_scu.h>
@@ -36,14 +37,13 @@
36#define SBAR IOMEM(0xe6180020) 37#define SBAR IOMEM(0xe6180020)
37#define APARMBAREA IOMEM(0xe6f10020) 38#define APARMBAREA IOMEM(0xe6f10020)
38 39
40#define PSTR_SHUTDOWN_MODE 3
41
39static void __iomem *scu_base_addr(void) 42static void __iomem *scu_base_addr(void)
40{ 43{
41 return (void __iomem *)0xf0000000; 44 return (void __iomem *)0xf0000000;
42} 45}
43 46
44static DEFINE_SPINLOCK(scu_lock);
45static unsigned long tmp;
46
47#ifdef CONFIG_HAVE_ARM_TWD 47#ifdef CONFIG_HAVE_ARM_TWD
48static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); 48static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
49void __init sh73a0_register_twd(void) 49void __init sh73a0_register_twd(void)
@@ -52,20 +52,6 @@ void __init sh73a0_register_twd(void)
52} 52}
53#endif 53#endif
54 54
55static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
56{
57 void __iomem *scu_base = scu_base_addr();
58
59 spin_lock(&scu_lock);
60 tmp = __raw_readl(scu_base + 8);
61 tmp &= ~clr;
62 tmp |= set;
63 spin_unlock(&scu_lock);
64
65 /* disable cache coherency after releasing the lock */
66 __raw_writel(tmp, scu_base + 8);
67}
68
69static unsigned int __init sh73a0_get_core_count(void) 55static unsigned int __init sh73a0_get_core_count(void)
70{ 56{
71 void __iomem *scu_base = scu_base_addr(); 57 void __iomem *scu_base = scu_base_addr();
@@ -82,9 +68,6 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct
82{ 68{
83 cpu = cpu_logical_map(cpu); 69 cpu = cpu_logical_map(cpu);
84 70
85 /* enable cache coherency */
86 modify_scu_cpu_psr(0, 3 << (cpu * 8));
87
88 if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) 71 if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3)
89 __raw_writel(1 << cpu, WUPCR); /* wake up */ 72 __raw_writel(1 << cpu, WUPCR); /* wake up */
90 else 73 else
@@ -95,16 +78,14 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct
95 78
96static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) 79static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
97{ 80{
98 int cpu = cpu_logical_map(0);
99
100 scu_enable(scu_base_addr()); 81 scu_enable(scu_base_addr());
101 82
102 /* Map the reset vector (in headsmp.S) */ 83 /* Map the reset vector (in headsmp-sh73a0.S) */
103 __raw_writel(0, APARMBAREA); /* 4k */ 84 __raw_writel(0, APARMBAREA); /* 4k */
104 __raw_writel(__pa(shmobile_secondary_vector), SBAR); 85 __raw_writel(__pa(sh73a0_secondary_vector), SBAR);
105 86
106 /* enable cache coherency on CPU0 */ 87 /* enable cache coherency on booting CPU */
107 modify_scu_cpu_psr(0, 3 << (cpu * 8)); 88 scu_power_mode(scu_base_addr(), SCU_PM_NORMAL);
108} 89}
109 90
110static void __init sh73a0_smp_init_cpus(void) 91static void __init sh73a0_smp_init_cpus(void)
@@ -114,16 +95,20 @@ static void __init sh73a0_smp_init_cpus(void)
114 shmobile_smp_init_cpus(ncores); 95 shmobile_smp_init_cpus(ncores);
115} 96}
116 97
117static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu) 98#ifdef CONFIG_HOTPLUG_CPU
99static int sh73a0_cpu_kill(unsigned int cpu)
118{ 100{
101
119 int k; 102 int k;
103 u32 pstr;
120 104
121 /* this function is running on another CPU than the offline target, 105 /*
122 * here we need wait for shutdown code in platform_cpu_die() to 106 * wait until the power status register confirms the shutdown of the
123 * finish before asking SoC-specific code to power off the CPU core. 107 * offline target
124 */ 108 */
125 for (k = 0; k < 1000; k++) { 109 for (k = 0; k < 1000; k++) {
126 if (shmobile_cpu_is_dead(cpu)) 110 pstr = (__raw_readl(PSTR) >> (4 * cpu)) & 3;
111 if (pstr == PSTR_SHUTDOWN_MODE)
127 return 1; 112 return 1;
128 113
129 mdelay(1); 114 mdelay(1);
@@ -132,6 +117,23 @@ static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu)
132 return 0; 117 return 0;
133} 118}
134 119
120static void sh73a0_cpu_die(unsigned int cpu)
121{
122 /*
123 * The ARM MPcore does not issue a cache coherency request for the L1
124 * cache when powering off single CPUs. We must take care of this and
125 * further caches.
126 */
127 dsb();
128 flush_cache_all();
129
130 /* Set power off mode. This takes the CPU out of the MP cluster */
131 scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF);
132
133 /* Enter shutdown mode */
134 cpu_do_idle();
135}
136#endif /* CONFIG_HOTPLUG_CPU */
135 137
136struct smp_operations sh73a0_smp_ops __initdata = { 138struct smp_operations sh73a0_smp_ops __initdata = {
137 .smp_init_cpus = sh73a0_smp_init_cpus, 139 .smp_init_cpus = sh73a0_smp_init_cpus,
@@ -140,7 +142,7 @@ struct smp_operations sh73a0_smp_ops __initdata = {
140 .smp_boot_secondary = sh73a0_boot_secondary, 142 .smp_boot_secondary = sh73a0_boot_secondary,
141#ifdef CONFIG_HOTPLUG_CPU 143#ifdef CONFIG_HOTPLUG_CPU
142 .cpu_kill = sh73a0_cpu_kill, 144 .cpu_kill = sh73a0_cpu_kill,
143 .cpu_die = shmobile_cpu_die, 145 .cpu_die = sh73a0_cpu_die,
144 .cpu_disable = shmobile_cpu_disable, 146 .cpu_disable = shmobile_cpu_disable_any,
145#endif 147#endif
146}; 148};
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
index fdbe54a11555..3d16d4dff01b 100644
--- a/arch/arm/mach-shmobile/timer.c
+++ b/arch/arm/mach-shmobile/timer.c
@@ -20,6 +20,7 @@
20 */ 20 */
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <asm/arch_timer.h>
23#include <asm/mach/time.h> 24#include <asm/mach/time.h>
24#include <asm/smp_twd.h> 25#include <asm/smp_twd.h>
25 26
@@ -62,4 +63,6 @@ void __init shmobile_earlytimer_init(void)
62 63
63void __init shmobile_timer_init(void) 64void __init shmobile_timer_init(void)
64{ 65{
66 arch_timer_of_register();
67 arch_timer_sched_clock_init();
65} 68}
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
index 9941caa94931..315edff610f2 100644
--- a/arch/arm/mach-socfpga/core.h
+++ b/arch/arm/mach-socfpga/core.h
@@ -20,7 +20,7 @@
20#ifndef __MACH_CORE_H 20#ifndef __MACH_CORE_H
21#define __MACH_CORE_H 21#define __MACH_CORE_H
22 22
23extern void secondary_startup(void); 23extern void socfpga_secondary_startup(void);
24extern void __iomem *socfpga_scu_base_addr; 24extern void __iomem *socfpga_scu_base_addr;
25 25
26extern void socfpga_init_clocks(void); 26extern void socfpga_init_clocks(void);
@@ -29,6 +29,8 @@ extern void socfpga_sysmgr_init(void);
29extern struct smp_operations socfpga_smp_ops; 29extern struct smp_operations socfpga_smp_ops;
30extern char secondary_trampoline, secondary_trampoline_end; 30extern char secondary_trampoline, secondary_trampoline_end;
31 31
32extern unsigned long cpu1start_addr;
33
32#define SOCFPGA_SCU_VIRT_BASE 0xfffec000 34#define SOCFPGA_SCU_VIRT_BASE 0xfffec000
33 35
34#endif 36#endif
diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S
index f09b1283ffca..9004bfb1756e 100644
--- a/arch/arm/mach-socfpga/headsmp.S
+++ b/arch/arm/mach-socfpga/headsmp.S
@@ -13,13 +13,21 @@
13 __CPUINIT 13 __CPUINIT
14 .arch armv7-a 14 .arch armv7-a
15 15
16#define CPU1_START_ADDR 0xffd08010
17
18ENTRY(secondary_trampoline) 16ENTRY(secondary_trampoline)
19 movw r0, #:lower16:CPU1_START_ADDR 17 movw r2, #:lower16:cpu1start_addr
20 movt r0, #:upper16:CPU1_START_ADDR 18 movt r2, #:upper16:cpu1start_addr
19
20 /* The socfpga VT cannot handle a 0xC0000000 page offset when loading
21 the cpu1start_addr, we bit clear it. Tested on HW and VT. */
22 bic r2, r2, #0x40000000
21 23
24 ldr r0, [r2]
22 ldr r1, [r0] 25 ldr r1, [r0]
23 bx r1 26 bx r1
24 27
25ENTRY(secondary_trampoline_end) 28ENTRY(secondary_trampoline_end)
29
30ENTRY(socfpga_secondary_startup)
31 bl v7_invalidate_l1
32 b secondary_startup
33ENDPROC(socfpga_secondary_startup)
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
index 4e9e69d9e7de..84c60fa8daa0 100644
--- a/arch/arm/mach-socfpga/platsmp.c
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -47,16 +47,19 @@ static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct
47{ 47{
48 int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; 48 int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
49 49
50 memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); 50 if (cpu1start_addr) {
51 memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
51 52
52 __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10)); 53 __raw_writel(virt_to_phys(socfpga_secondary_startup),
54 (sys_manager_base_addr + (cpu1start_addr & 0x000000ff)));
53 55
54 flush_cache_all(); 56 flush_cache_all();
55 smp_wmb(); 57 smp_wmb();
56 outer_clean_range(0, trampoline_size); 58 outer_clean_range(0, trampoline_size);
57 59
58 /* This will release CPU #1 out of reset.*/ 60 /* This will release CPU #1 out of reset.*/
59 __raw_writel(0, rst_manager_base_addr + 0x10); 61 __raw_writel(0, rst_manager_base_addr + 0x10);
62 }
60 63
61 return 0; 64 return 0;
62} 65}
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index 27d68468a027..1042c023cf24 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -29,6 +29,7 @@
29void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE)); 29void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
30void __iomem *sys_manager_base_addr; 30void __iomem *sys_manager_base_addr;
31void __iomem *rst_manager_base_addr; 31void __iomem *rst_manager_base_addr;
32unsigned long cpu1start_addr;
32 33
33static struct map_desc scu_io_desc __initdata = { 34static struct map_desc scu_io_desc __initdata = {
34 .virtual = SOCFPGA_SCU_VIRT_BASE, 35 .virtual = SOCFPGA_SCU_VIRT_BASE,
@@ -67,6 +68,11 @@ void __init socfpga_sysmgr_init(void)
67 struct device_node *np; 68 struct device_node *np;
68 69
69 np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr"); 70 np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
71
72 if (of_property_read_u32(np, "cpu1-start-addr",
73 (u32 *) &cpu1start_addr))
74 pr_err("SMP: Need cpu1-start-addr in device tree.\n");
75
70 sys_manager_base_addr = of_iomap(np, 0); 76 sys_manager_base_addr = of_iomap(np, 0);
71 77
72 np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); 78 np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
@@ -93,7 +99,6 @@ static void __init socfpga_cyclone5_init(void)
93 99
94static const char *altera_dt_match[] = { 100static const char *altera_dt_match[] = {
95 "altr,socfpga", 101 "altr,socfpga",
96 "altr,socfpga-cyclone5",
97 NULL 102 NULL
98}; 103};
99 104
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 1ec7f80e2af5..d1c4893894ce 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -4,7 +4,7 @@ comment "NVIDIA Tegra options"
4 4
5config ARCH_TEGRA_2x_SOC 5config ARCH_TEGRA_2x_SOC
6 bool "Enable support for Tegra20 family" 6 bool "Enable support for Tegra20 family"
7 select ARCH_REQUIRE_GPIOLIB 7 select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
8 select ARM_ERRATA_720789 8 select ARM_ERRATA_720789
9 select ARM_ERRATA_742230 if SMP 9 select ARM_ERRATA_742230 if SMP
10 select ARM_ERRATA_751472 10 select ARM_ERRATA_751472
@@ -26,7 +26,6 @@ config ARCH_TEGRA_2x_SOC
26 26
27config ARCH_TEGRA_3x_SOC 27config ARCH_TEGRA_3x_SOC
28 bool "Enable support for Tegra30 family" 28 bool "Enable support for Tegra30 family"
29 select ARCH_REQUIRE_GPIOLIB
30 select ARM_ERRATA_743622 29 select ARM_ERRATA_743622
31 select ARM_ERRATA_751472 30 select ARM_ERRATA_751472
32 select ARM_ERRATA_754322 31 select ARM_ERRATA_754322
@@ -44,6 +43,18 @@ config ARCH_TEGRA_3x_SOC
44 Support for NVIDIA Tegra T30 processor family, based on the 43 Support for NVIDIA Tegra T30 processor family, based on the
45 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller 44 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
46 45
46config ARCH_TEGRA_114_SOC
47 bool "Enable support for Tegra114 family"
48 select ARM_ARCH_TIMER
49 select ARM_GIC
50 select ARM_L1_CACHE_SHIFT_6
51 select CPU_V7
52 select PINCTRL
53 select PINCTRL_TEGRA114
54 help
55 Support for NVIDIA Tegra T114 processor family, based on the
56 ARM CortexA15MP CPU
57
47config TEGRA_PCI 58config TEGRA_PCI
48 bool "PCI Express support" 59 bool "PCI Express support"
49 depends on ARCH_TEGRA_2x_SOC 60 depends on ARCH_TEGRA_2x_SOC
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index f0520961bafe..f6b46ae2b7f8 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,7 +1,6 @@
1obj-y += common.o 1obj-y += common.o
2obj-y += io.o 2obj-y += io.o
3obj-y += irq.o 3obj-y += irq.o
4obj-y += clock.o
5obj-y += fuse.o 4obj-y += fuse.o
6obj-y += pmc.o 5obj-y += pmc.o
7obj-y += flowctrl.o 6obj-y += flowctrl.o
@@ -12,16 +11,12 @@ obj-y += reset.o
12obj-y += reset-handler.o 11obj-y += reset-handler.o
13obj-y += sleep.o 12obj-y += sleep.o
14obj-$(CONFIG_CPU_IDLE) += cpuidle.o 13obj-$(CONFIG_CPU_IDLE) += cpuidle.o
15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o
16obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o
17obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o 14obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
18obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o 15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
19obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o 16obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
20ifeq ($(CONFIG_CPU_IDLE),y) 17ifeq ($(CONFIG_CPU_IDLE),y)
21obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o 18obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
22endif 19endif
23obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o
24obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks_data.o
25obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o 20obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o
26obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o 21obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
27ifeq ($(CONFIG_CPU_IDLE),y) 22ifeq ($(CONFIG_CPU_IDLE),y)
@@ -34,6 +29,10 @@ obj-$(CONFIG_TEGRA_PCI) += pcie.o
34 29
35obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o 30obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o
36obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o 31obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
32obj-$(CONFIG_ARCH_TEGRA_114_SOC) += board-dt-tegra114.o
33ifeq ($(CONFIG_CPU_IDLE),y)
34obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
35endif
37 36
38obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-harmony-pcie.o 37obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-harmony-pcie.o
39 38
diff --git a/arch/arm/mach-tegra/board-dt-tegra114.c b/arch/arm/mach-tegra/board-dt-tegra114.c
new file mode 100644
index 000000000000..085d63637b62
--- /dev/null
+++ b/arch/arm/mach-tegra/board-dt-tegra114.c
@@ -0,0 +1,46 @@
1/*
2 * NVIDIA Tegra114 device tree board support
3 *
4 * Copyright (C) 2013 NVIDIA Corporation
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/of.h>
18#include <linux/of_platform.h>
19#include <linux/clocksource.h>
20
21#include <asm/mach/arch.h>
22
23#include "board.h"
24#include "common.h"
25
26static void __init tegra114_dt_init(void)
27{
28 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
29}
30
31static const char * const tegra114_dt_board_compat[] = {
32 "nvidia,tegra114",
33 NULL,
34};
35
36DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)")
37 .smp = smp_ops(tegra_smp_ops),
38 .map_io = tegra_map_common_io,
39 .init_early = tegra114_init_early,
40 .init_irq = tegra_dt_init_irq,
41 .init_time = clocksource_of_init,
42 .init_machine = tegra114_dt_init,
43 .init_late = tegra_init_late,
44 .restart = tegra_assert_system_reset,
45 .dt_compat = tegra114_dt_board_compat,
46MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index d320f7ad7350..a0edf2510280 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -40,7 +40,6 @@
40#include <asm/setup.h> 40#include <asm/setup.h>
41 41
42#include "board.h" 42#include "board.h"
43#include "clock.h"
44#include "common.h" 43#include "common.h"
45#include "iomap.h" 44#include "iomap.h"
46 45
@@ -69,70 +68,17 @@ static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
69}; 68};
70 69
71static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { 70static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
72 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), 71 OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0",
73 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL),
74 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL),
75 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC4_BASE, "sdhci-tegra.3", NULL),
76 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL),
77 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL),
78 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL),
79 OF_DEV_AUXDATA("nvidia,tegra20-i2c-dvc", TEGRA_DVC_BASE, "tegra-i2c.3", NULL),
80 OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra20-i2s.0", NULL),
81 OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S2_BASE, "tegra20-i2s.1", NULL),
82 OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra20-das", NULL),
83 OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB_BASE, "tegra-ehci.0",
84 &tegra_ehci1_pdata), 72 &tegra_ehci1_pdata),
85 OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1", 73 OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1",
86 &tegra_ehci2_pdata), 74 &tegra_ehci2_pdata),
87 OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", 75 OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2",
88 &tegra_ehci3_pdata), 76 &tegra_ehci3_pdata),
89 OF_DEV_AUXDATA("nvidia,tegra20-apbdma", TEGRA_APB_DMA_BASE, "tegra-apbdma", NULL),
90 OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
91 OF_DEV_AUXDATA("nvidia,tegra20-sflash", 0x7000c380, "spi", NULL),
92 OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D400, "spi_tegra.0", NULL),
93 OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D600, "spi_tegra.1", NULL),
94 OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D800, "spi_tegra.2", NULL),
95 OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000DA00, "spi_tegra.3", NULL),
96 OF_DEV_AUXDATA("nvidia,tegra20-host1x", 0x50000000, "host1x", NULL),
97 OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54200000, "tegradc.0", NULL),
98 OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54240000, "tegradc.1", NULL),
99 OF_DEV_AUXDATA("nvidia,tegra20-hdmi", 0x54280000, "hdmi", NULL),
100 OF_DEV_AUXDATA("nvidia,tegra20-dsi", 0x54300000, "dsi", NULL),
101 OF_DEV_AUXDATA("nvidia,tegra20-tvo", 0x542c0000, "tvo", NULL),
102 {} 77 {}
103}; 78};
104 79
105static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
106 /* name parent rate enabled */
107 { "uarta", "pll_p", 216000000, true },
108 { "uartd", "pll_p", 216000000, true },
109 { "usbd", "clk_m", 12000000, false },
110 { "usb2", "clk_m", 12000000, false },
111 { "usb3", "clk_m", 12000000, false },
112 { "pll_a", "pll_p_out1", 56448000, true },
113 { "pll_a_out0", "pll_a", 11289600, true },
114 { "cdev1", NULL, 0, true },
115 { "blink", "clk_32k", 32768, true },
116 { "i2s1", "pll_a_out0", 11289600, false},
117 { "i2s2", "pll_a_out0", 11289600, false},
118 { "sdmmc1", "pll_p", 48000000, false},
119 { "sdmmc3", "pll_p", 48000000, false},
120 { "sdmmc4", "pll_p", 48000000, false},
121 { "spi", "pll_p", 20000000, false },
122 { "sbc1", "pll_p", 100000000, false },
123 { "sbc2", "pll_p", 100000000, false },
124 { "sbc3", "pll_p", 100000000, false },
125 { "sbc4", "pll_p", 100000000, false },
126 { "host1x", "pll_c", 150000000, false },
127 { "disp1", "pll_p", 600000000, false },
128 { "disp2", "pll_p", 600000000, false },
129 { NULL, NULL, 0, 0},
130};
131
132static void __init tegra_dt_init(void) 80static void __init tegra_dt_init(void)
133{ 81{
134 tegra_clk_init_from_table(tegra_dt_clk_init_table);
135
136 /* 82 /*
137 * Finished with the static registrations now; fill in the missing 83 * Finished with the static registrations now; fill in the missing
138 * devices 84 * devices
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 97e1f67fc31d..bf68567e549d 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -34,72 +34,12 @@
34#include <asm/mach/arch.h> 34#include <asm/mach/arch.h>
35 35
36#include "board.h" 36#include "board.h"
37#include "clock.h"
38#include "common.h" 37#include "common.h"
39#include "iomap.h" 38#include "iomap.h"
40 39
41static struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
42 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
43 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL),
44 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL),
45 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000600, "sdhci-tegra.3", NULL),
46 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C000, "tegra-i2c.0", NULL),
47 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C400, "tegra-i2c.1", NULL),
48 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL),
49 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL),
50 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
51 OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL),
52 OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL),
53 OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
54 OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D400, "spi_tegra.0", NULL),
55 OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D600, "spi_tegra.1", NULL),
56 OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D800, "spi_tegra.2", NULL),
57 OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DA00, "spi_tegra.3", NULL),
58 OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DC00, "spi_tegra.4", NULL),
59 OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DE00, "spi_tegra.5", NULL),
60 OF_DEV_AUXDATA("nvidia,tegra30-host1x", 0x50000000, "host1x", NULL),
61 OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54200000, "tegradc.0", NULL),
62 OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54240000, "tegradc.1", NULL),
63 OF_DEV_AUXDATA("nvidia,tegra30-hdmi", 0x54280000, "hdmi", NULL),
64 OF_DEV_AUXDATA("nvidia,tegra30-dsi", 0x54300000, "dsi", NULL),
65 OF_DEV_AUXDATA("nvidia,tegra30-tvo", 0x542c0000, "tvo", NULL),
66 {}
67};
68
69static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
70 /* name parent rate enabled */
71 { "uarta", "pll_p", 408000000, true },
72 { "pll_a", "pll_p_out1", 564480000, true },
73 { "pll_a_out0", "pll_a", 11289600, true },
74 { "extern1", "pll_a_out0", 0, true },
75 { "clk_out_1", "extern1", 0, true },
76 { "blink", "clk_32k", 32768, true },
77 { "i2s0", "pll_a_out0", 11289600, false},
78 { "i2s1", "pll_a_out0", 11289600, false},
79 { "i2s2", "pll_a_out0", 11289600, false},
80 { "i2s3", "pll_a_out0", 11289600, false},
81 { "i2s4", "pll_a_out0", 11289600, false},
82 { "sdmmc1", "pll_p", 48000000, false},
83 { "sdmmc3", "pll_p", 48000000, false},
84 { "sdmmc4", "pll_p", 48000000, false},
85 { "sbc1", "pll_p", 100000000, false},
86 { "sbc2", "pll_p", 100000000, false},
87 { "sbc3", "pll_p", 100000000, false},
88 { "sbc4", "pll_p", 100000000, false},
89 { "sbc5", "pll_p", 100000000, false},
90 { "sbc6", "pll_p", 100000000, false},
91 { "host1x", "pll_c", 150000000, false},
92 { "disp1", "pll_p", 600000000, false},
93 { "disp2", "pll_p", 600000000, false},
94 { NULL, NULL, 0, 0},
95};
96
97static void __init tegra30_dt_init(void) 40static void __init tegra30_dt_init(void)
98{ 41{
99 tegra_clk_init_from_table(tegra_dt_clk_init_table); 42 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
100
101 of_platform_populate(NULL, of_default_bus_match_table,
102 tegra30_auxdata_lookup, NULL);
103} 43}
104 44
105static const char *tegra30_dt_board_compat[] = { 45static const char *tegra30_dt_board_compat[] = {
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index da8f5a3c4240..86851c81a350 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * arch/arm/mach-tegra/board.h 2 * arch/arm/mach-tegra/board.h
3 * 3 *
4 * Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
4 * Copyright (C) 2010 Google, Inc. 5 * Copyright (C) 2010 Google, Inc.
5 * 6 *
6 * Author: 7 * Author:
@@ -27,6 +28,7 @@ void tegra_assert_system_reset(char mode, const char *cmd);
27 28
28void __init tegra20_init_early(void); 29void __init tegra20_init_early(void);
29void __init tegra30_init_early(void); 30void __init tegra30_init_early(void);
31void __init tegra114_init_early(void);
30void __init tegra_map_common_io(void); 32void __init tegra_map_common_io(void);
31void __init tegra_init_irq(void); 33void __init tegra_init_irq(void);
32void __init tegra_dt_init_irq(void); 34void __init tegra_dt_init_irq(void);
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
deleted file mode 100644
index 867bf8bf5561..000000000000
--- a/arch/arm/mach-tegra/clock.c
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2 *
3 * Copyright (C) 2010 Google, Inc.
4 * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/clk.h>
22#include <linux/clkdev.h>
23#include <linux/init.h>
24#include <linux/list.h>
25#include <linux/module.h>
26#include <linux/sched.h>
27#include <linux/seq_file.h>
28#include <linux/slab.h>
29
30#include "board.h"
31#include "clock.h"
32#include "tegra_cpu_car.h"
33
34/* Global data of Tegra CPU CAR ops */
35struct tegra_cpu_car_ops *tegra_cpu_car_ops;
36
37/*
38 * Locking:
39 *
40 * An additional mutex, clock_list_lock, is used to protect the list of all
41 * clocks.
42 *
43 */
44static DEFINE_MUTEX(clock_list_lock);
45static LIST_HEAD(clocks);
46
47void tegra_clk_add(struct clk *clk)
48{
49 struct clk_tegra *c = to_clk_tegra(__clk_get_hw(clk));
50
51 mutex_lock(&clock_list_lock);
52 list_add(&c->node, &clocks);
53 mutex_unlock(&clock_list_lock);
54}
55
56struct clk *tegra_get_clock_by_name(const char *name)
57{
58 struct clk_tegra *c;
59 struct clk *ret = NULL;
60 mutex_lock(&clock_list_lock);
61 list_for_each_entry(c, &clocks, node) {
62 if (strcmp(__clk_get_name(c->hw.clk), name) == 0) {
63 ret = c->hw.clk;
64 break;
65 }
66 }
67 mutex_unlock(&clock_list_lock);
68 return ret;
69}
70
71static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
72{
73 struct clk *c;
74 struct clk *p;
75 struct clk *parent;
76
77 int ret = 0;
78
79 c = tegra_get_clock_by_name(table->name);
80
81 if (!c) {
82 pr_warn("Unable to initialize clock %s\n",
83 table->name);
84 return -ENODEV;
85 }
86
87 parent = clk_get_parent(c);
88
89 if (table->parent) {
90 p = tegra_get_clock_by_name(table->parent);
91 if (!p) {
92 pr_warn("Unable to find parent %s of clock %s\n",
93 table->parent, table->name);
94 return -ENODEV;
95 }
96
97 if (parent != p) {
98 ret = clk_set_parent(c, p);
99 if (ret) {
100 pr_warn("Unable to set parent %s of clock %s: %d\n",
101 table->parent, table->name, ret);
102 return -EINVAL;
103 }
104 }
105 }
106
107 if (table->rate && table->rate != clk_get_rate(c)) {
108 ret = clk_set_rate(c, table->rate);
109 if (ret) {
110 pr_warn("Unable to set clock %s to rate %lu: %d\n",
111 table->name, table->rate, ret);
112 return -EINVAL;
113 }
114 }
115
116 if (table->enabled) {
117 ret = clk_prepare_enable(c);
118 if (ret) {
119 pr_warn("Unable to enable clock %s: %d\n",
120 table->name, ret);
121 return -EINVAL;
122 }
123 }
124
125 return 0;
126}
127
128void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
129{
130 for (; table->name; table++)
131 tegra_clk_init_one_from_table(table);
132}
133
134void tegra_periph_reset_deassert(struct clk *c)
135{
136 struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
137 BUG_ON(!clk->reset);
138 clk->reset(__clk_get_hw(c), false);
139}
140EXPORT_SYMBOL(tegra_periph_reset_deassert);
141
142void tegra_periph_reset_assert(struct clk *c)
143{
144 struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
145 BUG_ON(!clk->reset);
146 clk->reset(__clk_get_hw(c), true);
147}
148EXPORT_SYMBOL(tegra_periph_reset_assert);
149
150/* Several extended clock configuration bits (e.g., clock routing, clock
151 * phase control) are included in PLL and peripheral clock source
152 * registers. */
153int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
154{
155 int ret = 0;
156 struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
157
158 if (!clk->clk_cfg_ex) {
159 ret = -ENOSYS;
160 goto out;
161 }
162 ret = clk->clk_cfg_ex(__clk_get_hw(c), p, setting);
163
164out:
165 return ret;
166}
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
deleted file mode 100644
index 2aa37f5c44c0..000000000000
--- a/arch/arm/mach-tegra/clock.h
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * arch/arm/mach-tegra/include/mach/clock.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
6 *
7 * Author:
8 * Colin Cross <ccross@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#ifndef __MACH_TEGRA_CLOCK_H
22#define __MACH_TEGRA_CLOCK_H
23
24#include <linux/clk-provider.h>
25#include <linux/clkdev.h>
26#include <linux/list.h>
27
28#include <mach/clk.h>
29
30#define DIV_BUS (1 << 0)
31#define DIV_U71 (1 << 1)
32#define DIV_U71_FIXED (1 << 2)
33#define DIV_2 (1 << 3)
34#define DIV_U16 (1 << 4)
35#define PLL_FIXED (1 << 5)
36#define PLL_HAS_CPCON (1 << 6)
37#define MUX (1 << 7)
38#define PLLD (1 << 8)
39#define PERIPH_NO_RESET (1 << 9)
40#define PERIPH_NO_ENB (1 << 10)
41#define PERIPH_EMC_ENB (1 << 11)
42#define PERIPH_MANUAL_RESET (1 << 12)
43#define PLL_ALT_MISC_REG (1 << 13)
44#define PLLU (1 << 14)
45#define PLLX (1 << 15)
46#define MUX_PWM (1 << 16)
47#define MUX8 (1 << 17)
48#define DIV_U71_UART (1 << 18)
49#define MUX_CLK_OUT (1 << 19)
50#define PLLM (1 << 20)
51#define DIV_U71_INT (1 << 21)
52#define DIV_U71_IDLE (1 << 22)
53#define ENABLE_ON_INIT (1 << 28)
54#define PERIPH_ON_APB (1 << 29)
55
56struct clk_tegra;
57#define to_clk_tegra(_hw) container_of(_hw, struct clk_tegra, hw)
58
59struct clk_mux_sel {
60 struct clk *input;
61 u32 value;
62};
63
64struct clk_pll_freq_table {
65 unsigned long input_rate;
66 unsigned long output_rate;
67 u16 n;
68 u16 m;
69 u8 p;
70 u8 cpcon;
71};
72
73enum clk_state {
74 UNINITIALIZED = 0,
75 ON,
76 OFF,
77};
78
79struct clk_tegra {
80 /* node for master clocks list */
81 struct list_head node; /* node for list of all clocks */
82 struct clk_lookup lookup;
83 struct clk_hw hw;
84
85 bool set;
86 unsigned long fixed_rate;
87 unsigned long max_rate;
88 unsigned long min_rate;
89 u32 flags;
90 const char *name;
91
92 enum clk_state state;
93 u32 div;
94 u32 mul;
95
96 u32 reg;
97 u32 reg_shift;
98
99 struct list_head shared_bus_list;
100
101 union {
102 struct {
103 unsigned int clk_num;
104 } periph;
105 struct {
106 unsigned long input_min;
107 unsigned long input_max;
108 unsigned long cf_min;
109 unsigned long cf_max;
110 unsigned long vco_min;
111 unsigned long vco_max;
112 const struct clk_pll_freq_table *freq_table;
113 int lock_delay;
114 unsigned long fixed_rate;
115 } pll;
116 struct {
117 u32 sel;
118 u32 reg_mask;
119 } mux;
120 struct {
121 struct clk *main;
122 struct clk *backup;
123 } cpu;
124 struct {
125 struct list_head node;
126 bool enabled;
127 unsigned long rate;
128 } shared_bus_user;
129 } u;
130
131 void (*reset)(struct clk_hw *, bool);
132 int (*clk_cfg_ex)(struct clk_hw *, enum tegra_clk_ex_param, u32);
133};
134
135struct clk_duplicate {
136 const char *name;
137 struct clk_lookup lookup;
138};
139
140struct tegra_clk_init_table {
141 const char *name;
142 const char *parent;
143 unsigned long rate;
144 bool enabled;
145};
146
147void tegra_clk_add(struct clk *c);
148void tegra2_init_clocks(void);
149void tegra30_init_clocks(void);
150struct clk *tegra_get_clock_by_name(const char *name);
151void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
152
153#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 8f0ffe97ffee..5449a3f2977b 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * arch/arm/mach-tegra/common.c 2 * arch/arm/mach-tegra/common.c
3 * 3 *
4 * Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
4 * Copyright (C) 2010 Google, Inc. 5 * Copyright (C) 2010 Google, Inc.
5 * 6 *
6 * Author: 7 * Author:
@@ -22,13 +23,13 @@
22#include <linux/clk.h> 23#include <linux/clk.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/irqchip.h> 25#include <linux/irqchip.h>
26#include <linux/clk/tegra.h>
25 27
26#include <asm/hardware/cache-l2x0.h> 28#include <asm/hardware/cache-l2x0.h>
27 29
28#include <mach/powergate.h> 30#include <mach/powergate.h>
29 31
30#include "board.h" 32#include "board.h"
31#include "clock.h"
32#include "common.h" 33#include "common.h"
33#include "fuse.h" 34#include "fuse.h"
34#include "iomap.h" 35#include "iomap.h"
@@ -59,6 +60,7 @@ u32 tegra_uart_config[4] = {
59#ifdef CONFIG_OF 60#ifdef CONFIG_OF
60void __init tegra_dt_init_irq(void) 61void __init tegra_dt_init_irq(void)
61{ 62{
63 tegra_clocks_init();
62 tegra_init_irq(); 64 tegra_init_irq();
63 irqchip_init(); 65 irqchip_init();
64} 66}
@@ -74,43 +76,6 @@ void tegra_assert_system_reset(char mode, const char *cmd)
74 writel_relaxed(reg, reset); 76 writel_relaxed(reg, reset);
75} 77}
76 78
77#ifdef CONFIG_ARCH_TEGRA_2x_SOC
78static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = {
79 /* name parent rate enabled */
80 { "clk_m", NULL, 0, true },
81 { "pll_p", "clk_m", 216000000, true },
82 { "pll_p_out1", "pll_p", 28800000, true },
83 { "pll_p_out2", "pll_p", 48000000, true },
84 { "pll_p_out3", "pll_p", 72000000, true },
85 { "pll_p_out4", "pll_p", 24000000, true },
86 { "pll_c", "clk_m", 600000000, true },
87 { "pll_c_out1", "pll_c", 120000000, true },
88 { "sclk", "pll_c_out1", 120000000, true },
89 { "hclk", "sclk", 120000000, true },
90 { "pclk", "hclk", 60000000, true },
91 { "csite", NULL, 0, true },
92 { "emc", NULL, 0, true },
93 { "cpu", NULL, 0, true },
94 { NULL, NULL, 0, 0},
95};
96#endif
97
98#ifdef CONFIG_ARCH_TEGRA_3x_SOC
99static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = {
100 /* name parent rate enabled */
101 { "clk_m", NULL, 0, true },
102 { "pll_p", "pll_ref", 408000000, true },
103 { "pll_p_out1", "pll_p", 9600000, true },
104 { "pll_p_out4", "pll_p", 102000000, true },
105 { "sclk", "pll_p_out4", 102000000, true },
106 { "hclk", "sclk", 102000000, true },
107 { "pclk", "hclk", 51000000, true },
108 { "csite", NULL, 0, true },
109 { NULL, NULL, 0, 0},
110};
111#endif
112
113
114static void __init tegra_init_cache(void) 79static void __init tegra_init_cache(void)
115{ 80{
116#ifdef CONFIG_CACHE_L2X0 81#ifdef CONFIG_CACHE_L2X0
@@ -129,35 +94,39 @@ static void __init tegra_init_cache(void)
129 94
130} 95}
131 96
132#ifdef CONFIG_ARCH_TEGRA_2x_SOC 97static void __init tegra_init_early(void)
133void __init tegra20_init_early(void)
134{ 98{
135 tegra_cpu_reset_handler_init(); 99 tegra_cpu_reset_handler_init();
136 tegra_apb_io_init(); 100 tegra_apb_io_init();
137 tegra_init_fuse(); 101 tegra_init_fuse();
138 tegra2_init_clocks();
139 tegra_clk_init_from_table(tegra20_clk_init_table);
140 tegra_init_cache(); 102 tegra_init_cache();
141 tegra_pmc_init(); 103 tegra_pmc_init();
142 tegra_powergate_init(); 104 tegra_powergate_init();
105}
106
107#ifdef CONFIG_ARCH_TEGRA_2x_SOC
108void __init tegra20_init_early(void)
109{
110 tegra_init_early();
143 tegra20_hotplug_init(); 111 tegra20_hotplug_init();
144} 112}
145#endif 113#endif
114
146#ifdef CONFIG_ARCH_TEGRA_3x_SOC 115#ifdef CONFIG_ARCH_TEGRA_3x_SOC
147void __init tegra30_init_early(void) 116void __init tegra30_init_early(void)
148{ 117{
149 tegra_cpu_reset_handler_init(); 118 tegra_init_early();
150 tegra_apb_io_init();
151 tegra_init_fuse();
152 tegra30_init_clocks();
153 tegra_clk_init_from_table(tegra30_clk_init_table);
154 tegra_init_cache();
155 tegra_pmc_init();
156 tegra_powergate_init();
157 tegra30_hotplug_init(); 119 tegra30_hotplug_init();
158} 120}
159#endif 121#endif
160 122
123#ifdef CONFIG_ARCH_TEGRA_114_SOC
124void __init tegra114_init_early(void)
125{
126 tegra_init_early();
127}
128#endif
129
161void __init tegra_init_late(void) 130void __init tegra_init_late(void)
162{ 131{
163 tegra_powergate_debugfs_init(); 132 tegra_powergate_debugfs_init();
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index ece29ab15b59..e3d6e15ff188 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -265,7 +265,7 @@ static int __init tegra_cpufreq_init(void)
265 if (IS_ERR(pll_x_clk)) 265 if (IS_ERR(pll_x_clk))
266 return PTR_ERR(pll_x_clk); 266 return PTR_ERR(pll_x_clk);
267 267
268 pll_p_clk = clk_get_sys(NULL, "pll_p"); 268 pll_p_clk = clk_get_sys(NULL, "pll_p_cclk");
269 if (IS_ERR(pll_p_clk)) 269 if (IS_ERR(pll_p_clk))
270 return PTR_ERR(pll_p_clk); 270 return PTR_ERR(pll_p_clk);
271 271
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
new file mode 100644
index 000000000000..0f4e8c483b34
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/cpuidle.h>
20
21#include <asm/cpuidle.h>
22
23static struct cpuidle_driver tegra_idle_driver = {
24 .name = "tegra_idle",
25 .owner = THIS_MODULE,
26 .en_core_tk_irqen = 1,
27 .state_count = 1,
28 .states = {
29 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
30 },
31};
32
33static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
34
35int __init tegra114_cpuidle_init(void)
36{
37 int ret;
38 unsigned int cpu;
39 struct cpuidle_device *dev;
40 struct cpuidle_driver *drv = &tegra_idle_driver;
41
42 ret = cpuidle_register_driver(&tegra_idle_driver);
43 if (ret) {
44 pr_err("CPUidle driver registration failed\n");
45 return ret;
46 }
47
48 for_each_possible_cpu(cpu) {
49 dev = &per_cpu(tegra_idle_device, cpu);
50 dev->cpu = cpu;
51
52 dev->state_count = drv->state_count;
53 ret = cpuidle_register_device(dev);
54 if (ret) {
55 pr_err("CPU%u: CPUidle device registration failed\n",
56 cpu);
57 return ret;
58 }
59 }
60 return 0;
61}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index d32e8b0dbd4f..825ced4f7a40 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -22,21 +22,199 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/cpuidle.h> 24#include <linux/cpuidle.h>
25#include <linux/cpu_pm.h>
26#include <linux/clockchips.h>
27#include <linux/clk/tegra.h>
25 28
26#include <asm/cpuidle.h> 29#include <asm/cpuidle.h>
30#include <asm/proc-fns.h>
31#include <asm/suspend.h>
32#include <asm/smp_plat.h>
33
34#include "pm.h"
35#include "sleep.h"
36#include "iomap.h"
37#include "irq.h"
38#include "flowctrl.h"
39
40#ifdef CONFIG_PM_SLEEP
41static bool abort_flag;
42static atomic_t abort_barrier;
43static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
44 struct cpuidle_driver *drv,
45 int index);
46#endif
47
48static struct cpuidle_state tegra_idle_states[] = {
49 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
50#ifdef CONFIG_PM_SLEEP
51 [1] = {
52 .enter = tegra20_idle_lp2_coupled,
53 .exit_latency = 5000,
54 .target_residency = 10000,
55 .power_usage = 0,
56 .flags = CPUIDLE_FLAG_TIME_VALID |
57 CPUIDLE_FLAG_COUPLED,
58 .name = "powered-down",
59 .desc = "CPU power gated",
60 },
61#endif
62};
27 63
28static struct cpuidle_driver tegra_idle_driver = { 64static struct cpuidle_driver tegra_idle_driver = {
29 .name = "tegra_idle", 65 .name = "tegra_idle",
30 .owner = THIS_MODULE, 66 .owner = THIS_MODULE,
31 .en_core_tk_irqen = 1, 67 .en_core_tk_irqen = 1,
32 .state_count = 1,
33 .states = {
34 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
35 },
36}; 68};
37 69
38static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); 70static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
39 71
72#ifdef CONFIG_PM_SLEEP
73#ifdef CONFIG_SMP
74static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
75
76static int tegra20_reset_sleeping_cpu_1(void)
77{
78 int ret = 0;
79
80 tegra_pen_lock();
81
82 if (readl(pmc + PMC_SCRATCH41) == CPU_RESETTABLE)
83 tegra20_cpu_shutdown(1);
84 else
85 ret = -EINVAL;
86
87 tegra_pen_unlock();
88
89 return ret;
90}
91
92static void tegra20_wake_cpu1_from_reset(void)
93{
94 tegra_pen_lock();
95
96 tegra20_cpu_clear_resettable();
97
98 /* enable cpu clock on cpu */
99 tegra_enable_cpu_clock(1);
100
101 /* take the CPU out of reset */
102 tegra_cpu_out_of_reset(1);
103
104 /* unhalt the cpu */
105 flowctrl_write_cpu_halt(1, 0);
106
107 tegra_pen_unlock();
108}
109
110static int tegra20_reset_cpu_1(void)
111{
112 if (!cpu_online(1) || !tegra20_reset_sleeping_cpu_1())
113 return 0;
114
115 tegra20_wake_cpu1_from_reset();
116 return -EBUSY;
117}
118#else
119static inline void tegra20_wake_cpu1_from_reset(void)
120{
121}
122
123static inline int tegra20_reset_cpu_1(void)
124{
125 return 0;
126}
127#endif
128
129static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
130 struct cpuidle_driver *drv,
131 int index)
132{
133 struct cpuidle_state *state = &drv->states[index];
134 u32 cpu_on_time = state->exit_latency;
135 u32 cpu_off_time = state->target_residency - state->exit_latency;
136
137 while (tegra20_cpu_is_resettable_soon())
138 cpu_relax();
139
140 if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready())
141 return false;
142
143 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
144
145 tegra_idle_lp2_last(cpu_on_time, cpu_off_time);
146
147 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
148
149 if (cpu_online(1))
150 tegra20_wake_cpu1_from_reset();
151
152 return true;
153}
154
155#ifdef CONFIG_SMP
156static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
157 struct cpuidle_driver *drv,
158 int index)
159{
160 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
161
162 cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
163
164 tegra20_cpu_clear_resettable();
165
166 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
167
168 return true;
169}
170#else
171static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
172 struct cpuidle_driver *drv,
173 int index)
174{
175 return true;
176}
177#endif
178
179static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
180 struct cpuidle_driver *drv,
181 int index)
182{
183 u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu;
184 bool entered_lp2 = false;
185
186 if (tegra_pending_sgi())
187 ACCESS_ONCE(abort_flag) = true;
188
189 cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
190
191 if (abort_flag) {
192 cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
193 abort_flag = false; /* clean flag for next coming */
194 return -EINTR;
195 }
196
197 local_fiq_disable();
198
199 tegra_set_cpu_in_lp2(cpu);
200 cpu_pm_enter();
201
202 if (cpu == 0)
203 entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index);
204 else
205 entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);
206
207 cpu_pm_exit();
208 tegra_clear_cpu_in_lp2(cpu);
209
210 local_fiq_enable();
211
212 smp_rmb();
213
214 return entered_lp2 ? index : 0;
215}
216#endif
217
40int __init tegra20_cpuidle_init(void) 218int __init tegra20_cpuidle_init(void)
41{ 219{
42 int ret; 220 int ret;
@@ -44,6 +222,14 @@ int __init tegra20_cpuidle_init(void)
44 struct cpuidle_device *dev; 222 struct cpuidle_device *dev;
45 struct cpuidle_driver *drv = &tegra_idle_driver; 223 struct cpuidle_driver *drv = &tegra_idle_driver;
46 224
225#ifdef CONFIG_PM_SLEEP
226 tegra_tear_down_cpu = tegra20_tear_down_cpu;
227#endif
228
229 drv->state_count = ARRAY_SIZE(tegra_idle_states);
230 memcpy(drv->states, tegra_idle_states,
231 drv->state_count * sizeof(drv->states[0]));
232
47 ret = cpuidle_register_driver(&tegra_idle_driver); 233 ret = cpuidle_register_driver(&tegra_idle_driver);
48 if (ret) { 234 if (ret) {
49 pr_err("CPUidle driver registration failed\n"); 235 pr_err("CPUidle driver registration failed\n");
@@ -53,6 +239,9 @@ int __init tegra20_cpuidle_init(void)
53 for_each_possible_cpu(cpu) { 239 for_each_possible_cpu(cpu) {
54 dev = &per_cpu(tegra_idle_device, cpu); 240 dev = &per_cpu(tegra_idle_device, cpu);
55 dev->cpu = cpu; 241 dev->cpu = cpu;
242#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
243 dev->coupled_cpus = *cpu_possible_mask;
244#endif
56 245
57 dev->state_count = drv->state_count; 246 dev->state_count = drv->state_count;
58 ret = cpuidle_register_device(dev); 247 ret = cpuidle_register_device(dev);
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
index 82530bd9b8c2..8b50cf4ddd6f 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -24,6 +24,7 @@
24#include <linux/cpuidle.h> 24#include <linux/cpuidle.h>
25#include <linux/cpu_pm.h> 25#include <linux/cpu_pm.h>
26#include <linux/clockchips.h> 26#include <linux/clockchips.h>
27#include <linux/clk/tegra.h>
27 28
28#include <asm/cpuidle.h> 29#include <asm/cpuidle.h>
29#include <asm/proc-fns.h> 30#include <asm/proc-fns.h>
@@ -32,7 +33,6 @@
32 33
33#include "pm.h" 34#include "pm.h"
34#include "sleep.h" 35#include "sleep.h"
35#include "tegra_cpu_car.h"
36 36
37#ifdef CONFIG_PM_SLEEP 37#ifdef CONFIG_PM_SLEEP
38static int tegra30_idle_lp2(struct cpuidle_device *dev, 38static int tegra30_idle_lp2(struct cpuidle_device *dev,
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index d0651397aec7..4b744c4661e2 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -38,6 +38,9 @@ static int __init tegra_cpuidle_init(void)
38 case TEGRA30: 38 case TEGRA30:
39 ret = tegra30_cpuidle_init(); 39 ret = tegra30_cpuidle_init();
40 break; 40 break;
41 case TEGRA114:
42 ret = tegra114_cpuidle_init();
43 break;
41 default: 44 default:
42 ret = -ENODEV; 45 ret = -ENODEV;
43 break; 46 break;
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h
index 496204d34e55..d733f75d0208 100644
--- a/arch/arm/mach-tegra/cpuidle.h
+++ b/arch/arm/mach-tegra/cpuidle.h
@@ -29,4 +29,10 @@ int tegra30_cpuidle_init(void);
29static inline int tegra30_cpuidle_init(void) { return -ENODEV; } 29static inline int tegra30_cpuidle_init(void) { return -ENODEV; }
30#endif 30#endif
31 31
32#ifdef CONFIG_ARCH_TEGRA_114_SOC
33int tegra114_cpuidle_init(void);
34#else
35static inline int tegra114_cpuidle_init(void) { return -ENODEV; }
36#endif
37
32#endif 38#endif
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index 5393eb2cae21..b477ef310dcd 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -25,6 +25,7 @@
25 25
26#include "flowctrl.h" 26#include "flowctrl.h"
27#include "iomap.h" 27#include "iomap.h"
28#include "fuse.h"
28 29
29static u8 flowctrl_offset_halt_cpu[] = { 30static u8 flowctrl_offset_halt_cpu[] = {
30 FLOW_CTRL_HALT_CPU0_EVENTS, 31 FLOW_CTRL_HALT_CPU0_EVENTS,
@@ -75,11 +76,26 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
75 int i; 76 int i;
76 77
77 reg = flowctrl_read_cpu_csr(cpuid); 78 reg = flowctrl_read_cpu_csr(cpuid);
78 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfe bitmap */ 79 switch (tegra_chip_id) {
79 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; /* clear wfi bitmap */ 80 case TEGRA20:
81 /* clear wfe bitmap */
82 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
83 /* clear wfi bitmap */
84 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
85 /* pwr gating on wfe */
86 reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid;
87 break;
88 case TEGRA30:
89 /* clear wfe bitmap */
90 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
91 /* clear wfi bitmap */
92 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
93 /* pwr gating on wfi */
94 reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
95 break;
96 }
80 reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */ 97 reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */
81 reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event flag */ 98 reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event flag */
82 reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid; /* pwr gating on wfi */
83 reg |= FLOW_CTRL_CSR_ENABLE; /* pwr gating */ 99 reg |= FLOW_CTRL_CSR_ENABLE; /* pwr gating */
84 flowctrl_write_cpu_csr(cpuid, reg); 100 flowctrl_write_cpu_csr(cpuid, reg);
85 101
@@ -99,8 +115,20 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)
99 115
100 /* Disable powergating via flow controller for CPU0 */ 116 /* Disable powergating via flow controller for CPU0 */
101 reg = flowctrl_read_cpu_csr(cpuid); 117 reg = flowctrl_read_cpu_csr(cpuid);
102 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfe bitmap */ 118 switch (tegra_chip_id) {
103 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; /* clear wfi bitmap */ 119 case TEGRA20:
120 /* clear wfe bitmap */
121 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
122 /* clear wfi bitmap */
123 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
124 break;
125 case TEGRA30:
126 /* clear wfe bitmap */
127 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
128 /* clear wfi bitmap */
129 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
130 break;
131 }
104 reg &= ~FLOW_CTRL_CSR_ENABLE; /* clear enable */ 132 reg &= ~FLOW_CTRL_CSR_ENABLE; /* clear enable */
105 reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr */ 133 reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr */
106 reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event */ 134 reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event */
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
index 0798dec1832d..67eab56699bd 100644
--- a/arch/arm/mach-tegra/flowctrl.h
+++ b/arch/arm/mach-tegra/flowctrl.h
@@ -34,6 +34,10 @@
34#define FLOW_CTRL_HALT_CPU1_EVENTS 0x14 34#define FLOW_CTRL_HALT_CPU1_EVENTS 0x14
35#define FLOW_CTRL_CPU1_CSR 0x18 35#define FLOW_CTRL_CPU1_CSR 0x18
36 36
37#define TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 (1 << 4)
38#define TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP (3 << 4)
39#define TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP 0
40
37#define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 (1 << 8) 41#define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 (1 << 8)
38#define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4) 42#define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4)
39#define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8) 43#define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8)
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index 8121742711fe..f7db0782a6b6 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -20,6 +20,7 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/export.h> 22#include <linux/export.h>
23#include <linux/tegra-soc.h>
23 24
24#include "fuse.h" 25#include "fuse.h"
25#include "iomap.h" 26#include "iomap.h"
@@ -105,6 +106,11 @@ static void tegra_get_process_id(void)
105 tegra_core_process_id = (reg >> 12) & 3; 106 tegra_core_process_id = (reg >> 12) & 3;
106} 107}
107 108
109u32 tegra_read_chipid(void)
110{
111 return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
112}
113
108void tegra_init_fuse(void) 114void tegra_init_fuse(void)
109{ 115{
110 u32 id; 116 u32 id;
@@ -119,7 +125,7 @@ void tegra_init_fuse(void)
119 reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT); 125 reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
120 tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT; 126 tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
121 127
122 id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804); 128 id = tegra_read_chipid();
123 tegra_chip_id = (id >> 8) & 0xff; 129 tegra_chip_id = (id >> 8) & 0xff;
124 130
125 switch (tegra_chip_id) { 131 switch (tegra_chip_id) {
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index ff1383dd61a7..da78434678c7 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -37,6 +37,7 @@ enum tegra_revision {
37 37
38#define TEGRA20 0x20 38#define TEGRA20 0x20
39#define TEGRA30 0x30 39#define TEGRA30 0x30
40#define TEGRA114 0x35
40 41
41extern int tegra_sku_id; 42extern int tegra_sku_id;
42extern int tegra_cpu_process_id; 43extern int tegra_cpu_process_id;
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
index b2834810b02b..fd473f2b4c3d 100644
--- a/arch/arm/mach-tegra/headsmp.S
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -5,49 +5,6 @@
5 5
6 .section ".text.head", "ax" 6 .section ".text.head", "ax"
7 7
8/*
9 * Tegra specific entry point for secondary CPUs.
10 * The secondary kernel init calls v7_flush_dcache_all before it enables
11 * the L1; however, the L1 comes out of reset in an undefined state, so
12 * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
13 * of cache lines with uninitialized data and uninitialized tags to get
14 * written out to memory, which does really unpleasant things to the main
15 * processor. We fix this by performing an invalidate, rather than a
16 * clean + invalidate, before jumping into the kernel.
17 */
18ENTRY(v7_invalidate_l1)
19 mov r0, #0
20 mcr p15, 2, r0, c0, c0, 0
21 mrc p15, 1, r0, c0, c0, 0
22
23 ldr r1, =0x7fff
24 and r2, r1, r0, lsr #13
25
26 ldr r1, =0x3ff
27
28 and r3, r1, r0, lsr #3 @ NumWays - 1
29 add r2, r2, #1 @ NumSets
30
31 and r0, r0, #0x7
32 add r0, r0, #4 @ SetShift
33
34 clz r1, r3 @ WayShift
35 add r4, r3, #1 @ NumWays
361: sub r2, r2, #1 @ NumSets--
37 mov r3, r4 @ Temp = NumWays
382: subs r3, r3, #1 @ Temp--
39 mov r5, r3, lsl r1
40 mov r6, r2, lsl r0
41 orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
42 mcr p15, 0, r5, c7, c6, 2
43 bgt 2b
44 cmp r2, #0
45 bgt 1b
46 dsb
47 isb
48 mov pc, lr
49ENDPROC(v7_invalidate_l1)
50
51ENTRY(tegra_secondary_startup) 8ENTRY(tegra_secondary_startup)
52 bl v7_invalidate_l1 9 bl v7_invalidate_l1
53 /* Enable coresight */ 10 /* Enable coresight */
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index 6a27de4001ee..a599f6e36dea 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -10,12 +10,12 @@
10 */ 10 */
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/smp.h> 12#include <linux/smp.h>
13#include <linux/clk/tegra.h>
13 14
14#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
15#include <asm/smp_plat.h> 16#include <asm/smp_plat.h>
16 17
17#include "sleep.h" 18#include "sleep.h"
18#include "tegra_cpu_car.h"
19 19
20static void (*tegra_hotplug_shutdown)(void); 20static void (*tegra_hotplug_shutdown)(void);
21 21
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
deleted file mode 100644
index 95f3a547c770..000000000000
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ /dev/null
@@ -1,44 +0,0 @@
1/*
2 * arch/arm/mach-tegra/include/mach/clk.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Erik Gilling <konkers@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#ifndef __MACH_CLK_H
21#define __MACH_CLK_H
22
23struct clk;
24
25enum tegra_clk_ex_param {
26 TEGRA_CLK_VI_INP_SEL,
27 TEGRA_CLK_DTV_INVERT,
28 TEGRA_CLK_NAND_PAD_DIV2_ENB,
29 TEGRA_CLK_PLLD_CSI_OUT_ENB,
30 TEGRA_CLK_PLLD_DSI_OUT_ENB,
31 TEGRA_CLK_PLLD_MIPI_MUX_SEL,
32};
33
34void tegra_periph_reset_deassert(struct clk *c);
35void tegra_periph_reset_assert(struct clk *c);
36
37#ifndef CONFIG_COMMON_CLK
38unsigned long clk_get_rate_all_locked(struct clk *c);
39#endif
40
41void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
42int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting);
43
44#endif
diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h
index db8be51cad80..399fbca27102 100644
--- a/arch/arm/mach-tegra/iomap.h
+++ b/arch/arm/mach-tegra/iomap.h
@@ -240,15 +240,6 @@
240#define TEGRA_CSITE_BASE 0x70040000 240#define TEGRA_CSITE_BASE 0x70040000
241#define TEGRA_CSITE_SIZE SZ_256K 241#define TEGRA_CSITE_SIZE SZ_256K
242 242
243#define TEGRA_USB_BASE 0xC5000000
244#define TEGRA_USB_SIZE SZ_16K
245
246#define TEGRA_USB2_BASE 0xC5004000
247#define TEGRA_USB2_SIZE SZ_16K
248
249#define TEGRA_USB3_BASE 0xC5008000
250#define TEGRA_USB3_SIZE SZ_16K
251
252#define TEGRA_SDMMC1_BASE 0xC8000000 243#define TEGRA_SDMMC1_BASE 0xC8000000
253#define TEGRA_SDMMC1_SIZE SZ_512 244#define TEGRA_SDMMC1_SIZE SZ_512
254 245
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 2ff2128cb9d8..1952e82797cc 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -44,6 +44,8 @@
44 44
45#define FIRST_LEGACY_IRQ 32 45#define FIRST_LEGACY_IRQ 32
46 46
47#define SGI_MASK 0xFFFF
48
47static int num_ictlrs; 49static int num_ictlrs;
48 50
49static void __iomem *ictlr_reg_base[] = { 51static void __iomem *ictlr_reg_base[] = {
@@ -54,6 +56,19 @@ static void __iomem *ictlr_reg_base[] = {
54 IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), 56 IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
55}; 57};
56 58
59bool tegra_pending_sgi(void)
60{
61 u32 pending_set;
62 void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
63
64 pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET);
65
66 if (pending_set & SGI_MASK)
67 return true;
68
69 return false;
70}
71
57static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) 72static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
58{ 73{
59 void __iomem *base; 74 void __iomem *base;
diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h
new file mode 100644
index 000000000000..5142649bba05
--- /dev/null
+++ b/arch/arm/mach-tegra/irq.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __TEGRA_IRQ_H
18#define __TEGRA_IRQ_H
19
20bool tegra_pending_sgi(void);
21
22#endif
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index bffcd643d7a3..b60165f1ca02 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -33,11 +33,11 @@
33#include <linux/clk.h> 33#include <linux/clk.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/export.h> 35#include <linux/export.h>
36#include <linux/clk/tegra.h>
36 37
37#include <asm/sizes.h> 38#include <asm/sizes.h>
38#include <asm/mach/pci.h> 39#include <asm/mach/pci.h>
39 40
40#include <mach/clk.h>
41#include <mach/powergate.h> 41#include <mach/powergate.h>
42 42
43#include "board.h" 43#include "board.h"
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 3c4a43c892a5..2c6b3d55213b 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -19,6 +19,7 @@
19#include <linux/smp.h> 19#include <linux/smp.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/irqchip/arm-gic.h> 21#include <linux/irqchip/arm-gic.h>
22#include <linux/clk/tegra.h>
22 23
23#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
24#include <asm/mach-types.h> 25#include <asm/mach-types.h>
@@ -30,7 +31,6 @@
30#include "fuse.h" 31#include "fuse.h"
31#include "flowctrl.h" 32#include "flowctrl.h"
32#include "reset.h" 33#include "reset.h"
33#include "tegra_cpu_car.h"
34 34
35#include "common.h" 35#include "common.h"
36#include "iomap.h" 36#include "iomap.h"
@@ -38,7 +38,6 @@
38extern void tegra_secondary_startup(void); 38extern void tegra_secondary_startup(void);
39 39
40static cpumask_t tegra_cpu_init_mask; 40static cpumask_t tegra_cpu_init_mask;
41static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
42 41
43#define EVP_CPU_RESET_VECTOR \ 42#define EVP_CPU_RESET_VECTOR \
44 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) 43 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
@@ -177,34 +176,16 @@ done:
177 return status; 176 return status;
178} 177}
179 178
180/*
181 * Initialise the CPU possible map early - this describes the CPUs
182 * which may be present or become present in the system.
183 */
184static void __init tegra_smp_init_cpus(void)
185{
186 unsigned int i, ncores = scu_get_core_count(scu_base);
187
188 if (ncores > nr_cpu_ids) {
189 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
190 ncores, nr_cpu_ids);
191 ncores = nr_cpu_ids;
192 }
193
194 for (i = 0; i < ncores; i++)
195 set_cpu_possible(i, true);
196}
197
198static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) 179static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
199{ 180{
200 /* Always mark the boot CPU (CPU0) as initialized. */ 181 /* Always mark the boot CPU (CPU0) as initialized. */
201 cpumask_set_cpu(0, &tegra_cpu_init_mask); 182 cpumask_set_cpu(0, &tegra_cpu_init_mask);
202 183
203 scu_enable(scu_base); 184 if (scu_a9_has_base())
185 scu_enable(IO_ADDRESS(scu_a9_get_base()));
204} 186}
205 187
206struct smp_operations tegra_smp_ops __initdata = { 188struct smp_operations tegra_smp_ops __initdata = {
207 .smp_init_cpus = tegra_smp_init_cpus,
208 .smp_prepare_cpus = tegra_smp_prepare_cpus, 189 .smp_prepare_cpus = tegra_smp_prepare_cpus,
209 .smp_secondary_init = tegra_secondary_init, 190 .smp_secondary_init = tegra_secondary_init,
210 .smp_boot_secondary = tegra_boot_secondary, 191 .smp_boot_secondary = tegra_boot_secondary,
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 498d70b33775..523604de666f 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -24,6 +24,7 @@
24#include <linux/cpu_pm.h> 24#include <linux/cpu_pm.h>
25#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/clk/tegra.h>
27 28
28#include <asm/smp_plat.h> 29#include <asm/smp_plat.h>
29#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
@@ -35,8 +36,8 @@
35#include "iomap.h" 36#include "iomap.h"
36#include "reset.h" 37#include "reset.h"
37#include "flowctrl.h" 38#include "flowctrl.h"
39#include "fuse.h"
38#include "sleep.h" 40#include "sleep.h"
39#include "tegra_cpu_car.h"
40 41
41#define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */ 42#define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */
42 43
@@ -173,6 +174,8 @@ bool tegra_set_cpu_in_lp2(int phy_cpu_id)
173 174
174 if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask)) 175 if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
175 last_cpu = true; 176 last_cpu = true;
177 else if (tegra_chip_id == TEGRA20 && phy_cpu_id == 1)
178 tegra20_cpu_set_resettable_soon();
176 179
177 spin_unlock(&tegra_lp2_lock); 180 spin_unlock(&tegra_lp2_lock);
178 return last_cpu; 181 return last_cpu;
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index 2cc1185d902e..c6bc8f85759c 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -26,8 +26,8 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/seq_file.h> 27#include <linux/seq_file.h>
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include <linux/clk/tegra.h>
29 30
30#include <mach/clk.h>
31#include <mach/powergate.h> 31#include <mach/powergate.h>
32 32
33#include "fuse.h" 33#include "fuse.h"
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index ad2ca07d0578..9f6bfafdd512 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -21,6 +21,8 @@
21#include <linux/linkage.h> 21#include <linux/linkage.h>
22 22
23#include <asm/assembler.h> 23#include <asm/assembler.h>
24#include <asm/proc-fns.h>
25#include <asm/cp15.h>
24 26
25#include "sleep.h" 27#include "sleep.h"
26#include "flowctrl.h" 28#include "flowctrl.h"
@@ -55,6 +57,9 @@ ENDPROC(tegra20_hotplug_shutdown)
55ENTRY(tegra20_cpu_shutdown) 57ENTRY(tegra20_cpu_shutdown)
56 cmp r0, #0 58 cmp r0, #0
57 moveq pc, lr @ must not be called for CPU 0 59 moveq pc, lr @ must not be called for CPU 0
60 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
61 mov r12, #CPU_RESETTABLE
62 str r12, [r1]
58 63
59 cpu_to_halt_reg r1, r0 64 cpu_to_halt_reg r1, r0
60 ldr r3, =TEGRA_FLOW_CTRL_VIRT 65 ldr r3, =TEGRA_FLOW_CTRL_VIRT
@@ -75,3 +80,198 @@ ENTRY(tegra20_cpu_shutdown)
75 mov pc, lr 80 mov pc, lr
76ENDPROC(tegra20_cpu_shutdown) 81ENDPROC(tegra20_cpu_shutdown)
77#endif 82#endif
83
84#ifdef CONFIG_PM_SLEEP
85/*
86 * tegra_pen_lock
87 *
88 * spinlock implementation with no atomic test-and-set and no coherence
89 * using Peterson's algorithm on strongly-ordered registers
90 * used to synchronize a cpu waking up from wfi with entering lp2 on idle
91 *
92 * The reference link of Peterson's algorithm:
93 * http://en.wikipedia.org/wiki/Peterson's_algorithm
94 *
95 * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
96 * on cpu 0:
97 * r2 = flag[0] (in SCRATCH38)
98 * r3 = flag[1] (in SCRATCH39)
99 * on cpu1:
100 * r2 = flag[1] (in SCRATCH39)
101 * r3 = flag[0] (in SCRATCH38)
102 *
103 * must be called with MMU on
104 * corrupts r0-r3, r12
105 */
106ENTRY(tegra_pen_lock)
107 mov32 r3, TEGRA_PMC_VIRT
108 cpu_id r0
109 add r1, r3, #PMC_SCRATCH37
110 cmp r0, #0
111 addeq r2, r3, #PMC_SCRATCH38
112 addeq r3, r3, #PMC_SCRATCH39
113 addne r2, r3, #PMC_SCRATCH39
114 addne r3, r3, #PMC_SCRATCH38
115
116 mov r12, #1
117 str r12, [r2] @ flag[cpu] = 1
118 dsb
119 str r12, [r1] @ !turn = cpu
1201: dsb
121 ldr r12, [r3]
122 cmp r12, #1 @ flag[!cpu] == 1?
123 ldreq r12, [r1]
124 cmpeq r12, r0 @ !turn == cpu?
125 beq 1b @ while !turn == cpu && flag[!cpu] == 1
126
127 mov pc, lr @ locked
128ENDPROC(tegra_pen_lock)
129
130ENTRY(tegra_pen_unlock)
131 dsb
132 mov32 r3, TEGRA_PMC_VIRT
133 cpu_id r0
134 cmp r0, #0
135 addeq r2, r3, #PMC_SCRATCH38
136 addne r2, r3, #PMC_SCRATCH39
137 mov r12, #0
138 str r12, [r2]
139 mov pc, lr
140ENDPROC(tegra_pen_unlock)
141
142/*
143 * tegra20_cpu_clear_resettable(void)
144 *
145 * Called to clear the "resettable soon" flag in PMC_SCRATCH41 when
146 * it is expected that the secondary CPU will be idle soon.
147 */
148ENTRY(tegra20_cpu_clear_resettable)
149 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
150 mov r12, #CPU_NOT_RESETTABLE
151 str r12, [r1]
152 mov pc, lr
153ENDPROC(tegra20_cpu_clear_resettable)
154
155/*
156 * tegra20_cpu_set_resettable_soon(void)
157 *
158 * Called to set the "resettable soon" flag in PMC_SCRATCH41 when
159 * it is expected that the secondary CPU will be idle soon.
160 */
161ENTRY(tegra20_cpu_set_resettable_soon)
162 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
163 mov r12, #CPU_RESETTABLE_SOON
164 str r12, [r1]
165 mov pc, lr
166ENDPROC(tegra20_cpu_set_resettable_soon)
167
168/*
169 * tegra20_cpu_is_resettable_soon(void)
170 *
171 * Returns true if the "resettable soon" flag in PMC_SCRATCH41 has been
172 * set because it is expected that the secondary CPU will be idle soon.
173 */
174ENTRY(tegra20_cpu_is_resettable_soon)
175 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
176 ldr r12, [r1]
177 cmp r12, #CPU_RESETTABLE_SOON
178 moveq r0, #1
179 movne r0, #0
180 mov pc, lr
181ENDPROC(tegra20_cpu_is_resettable_soon)
182
183/*
184 * tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
185 *
186 * Enters WFI on secondary CPU by exiting coherency.
187 */
188ENTRY(tegra20_sleep_cpu_secondary_finish)
189 stmfd sp!, {r4-r11, lr}
190
191 mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency
192
193 /* Flush and disable the L1 data cache */
194 bl tegra_disable_clean_inv_dcache
195
196 mov32 r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
197 mov r3, #CPU_RESETTABLE
198 str r3, [r0]
199
200 bl cpu_do_idle
201
202 /*
203 * cpu may be reset while in wfi, which will return through
204 * tegra_resume to cpu_resume
205 * or interrupt may wake wfi, which will return here
206 * cpu state is unchanged - MMU is on, cache is on, coherency
207 * is off, and the data cache is off
208 *
209 * r11 contains the original actlr
210 */
211
212 bl tegra_pen_lock
213
214 mov32 r3, TEGRA_PMC_VIRT
215 add r0, r3, #PMC_SCRATCH41
216 mov r3, #CPU_NOT_RESETTABLE
217 str r3, [r0]
218
219 bl tegra_pen_unlock
220
221 /* Re-enable the data cache */
222 mrc p15, 0, r10, c1, c0, 0
223 orr r10, r10, #CR_C
224 mcr p15, 0, r10, c1, c0, 0
225 isb
226
227 mcr p15, 0, r11, c1, c0, 1 @ reenable coherency
228
229 /* Invalidate the TLBs & BTAC */
230 mov r1, #0
231 mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs
232 mcr p15, 0, r1, c7, c1, 6 @ invalidate shared BTAC
233 dsb
234 isb
235
236 /* the cpu was running with coherency disabled,
237 * caches may be out of date */
238 bl v7_flush_kern_cache_louis
239
240 ldmfd sp!, {r4 - r11, pc}
241ENDPROC(tegra20_sleep_cpu_secondary_finish)
242
243/*
244 * tegra20_tear_down_cpu
245 *
246 * Switches the CPU cluster to PLL-P and enters sleep.
247 */
248ENTRY(tegra20_tear_down_cpu)
249 bl tegra_switch_cpu_to_pllp
250 b tegra20_enter_sleep
251ENDPROC(tegra20_tear_down_cpu)
252
253/*
254 * tegra20_enter_sleep
255 *
256 * uses flow controller to enter sleep state
257 * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
258 * executes from SDRAM with target state is LP2
259 */
260tegra20_enter_sleep:
261 mov32 r6, TEGRA_FLOW_CTRL_BASE
262
263 mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
264 orr r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
265 cpu_id r1
266 cpu_to_halt_reg r1, r1
267 str r0, [r6, r1]
268 dsb
269 ldr r0, [r6, r1] /* memory barrier */
270
271halted:
272 dsb
273 wfe /* CPU should be power gated here */
274 isb
275 b halted
276
277#endif
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index addae357da3f..364d84523fba 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -34,6 +34,9 @@
34#include "flowctrl.h" 34#include "flowctrl.h"
35#include "sleep.h" 35#include "sleep.h"
36 36
37#define CLK_RESET_CCLK_BURST 0x20
38#define CLK_RESET_CCLK_DIVIDER 0x24
39
37#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP) 40#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
38/* 41/*
39 * tegra_disable_clean_inv_dcache 42 * tegra_disable_clean_inv_dcache
@@ -110,4 +113,20 @@ ENTRY(tegra_shut_off_mmu)
110 mov pc, r0 113 mov pc, r0
111ENDPROC(tegra_shut_off_mmu) 114ENDPROC(tegra_shut_off_mmu)
112 .popsection 115 .popsection
116
117/*
118 * tegra_switch_cpu_to_pllp
119 *
120 * In LP2 the normal cpu clock pllx will be turned off. Switch the CPU to pllp
121 */
122ENTRY(tegra_switch_cpu_to_pllp)
123 /* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */
124 mov32 r5, TEGRA_CLK_RESET_BASE
125 mov r0, #(2 << 28) @ burst policy = run mode
126 orr r0, r0, #(4 << 4) @ use PLLP in run mode burst
127 str r0, [r5, #CLK_RESET_CCLK_BURST]
128 mov r0, #0
129 str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
130 mov pc, lr
131ENDPROC(tegra_switch_cpu_to_pllp)
113#endif 132#endif
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 56505c381ea8..4ffae541726e 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -25,6 +25,19 @@
25 + IO_PPSB_VIRT) 25 + IO_PPSB_VIRT)
26#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \ 26#define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
27 + IO_PPSB_VIRT) 27 + IO_PPSB_VIRT)
28#define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
29
30/* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */
31#define PMC_SCRATCH37 0x130
32#define PMC_SCRATCH38 0x134
33#define PMC_SCRATCH39 0x138
34#define PMC_SCRATCH41 0x140
35
36#ifdef CONFIG_ARCH_TEGRA_2x_SOC
37#define CPU_RESETTABLE 2
38#define CPU_RESETTABLE_SOON 1
39#define CPU_NOT_RESETTABLE 0
40#endif
28 41
29#ifdef __ASSEMBLY__ 42#ifdef __ASSEMBLY__
30/* returns the offset of the flow controller halt register for a cpu */ 43/* returns the offset of the flow controller halt register for a cpu */
@@ -104,6 +117,8 @@ exit_l2_resume:
104.endm 117.endm
105#endif /* CONFIG_CACHE_L2X0 */ 118#endif /* CONFIG_CACHE_L2X0 */
106#else 119#else
120void tegra_pen_lock(void);
121void tegra_pen_unlock(void);
107void tegra_resume(void); 122void tegra_resume(void);
108int tegra_sleep_cpu_finish(unsigned long); 123int tegra_sleep_cpu_finish(unsigned long);
109void tegra_disable_clean_inv_dcache(void); 124void tegra_disable_clean_inv_dcache(void);
@@ -116,6 +131,17 @@ static inline void tegra20_hotplug_init(void) {}
116static inline void tegra30_hotplug_init(void) {} 131static inline void tegra30_hotplug_init(void) {}
117#endif 132#endif
118 133
134void tegra20_cpu_shutdown(int cpu);
135int tegra20_cpu_is_resettable_soon(void);
136void tegra20_cpu_clear_resettable(void);
137#ifdef CONFIG_ARCH_TEGRA_2x_SOC
138void tegra20_cpu_set_resettable_soon(void);
139#else
140static inline void tegra20_cpu_set_resettable_soon(void) {}
141#endif
142
143int tegra20_sleep_cpu_secondary_finish(unsigned long);
144void tegra20_tear_down_cpu(void);
119int tegra30_sleep_cpu_secondary_finish(unsigned long); 145int tegra30_sleep_cpu_secondary_finish(unsigned long);
120void tegra30_tear_down_cpu(void); 146void tegra30_tear_down_cpu(void);
121 147
diff --git a/arch/arm/mach-tegra/tegra20_clocks.c b/arch/arm/mach-tegra/tegra20_clocks.c
deleted file mode 100644
index 4eb6bc81a87b..000000000000
--- a/arch/arm/mach-tegra/tegra20_clocks.c
+++ /dev/null
@@ -1,1623 +0,0 @@
1/*
2 * arch/arm/mach-tegra/tegra20_clocks.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved.
6 *
7 * Author:
8 * Colin Cross <ccross@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/list.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <linux/io.h>
27#include <linux/clkdev.h>
28#include <linux/clk.h>
29
30#include "clock.h"
31#include "fuse.h"
32#include "iomap.h"
33#include "tegra2_emc.h"
34#include "tegra_cpu_car.h"
35
36#define RST_DEVICES 0x004
37#define RST_DEVICES_SET 0x300
38#define RST_DEVICES_CLR 0x304
39#define RST_DEVICES_NUM 3
40
41#define CLK_OUT_ENB 0x010
42#define CLK_OUT_ENB_SET 0x320
43#define CLK_OUT_ENB_CLR 0x324
44#define CLK_OUT_ENB_NUM 3
45
46#define CLK_MASK_ARM 0x44
47#define MISC_CLK_ENB 0x48
48
49#define OSC_CTRL 0x50
50#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
51#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
52#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
53#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
54#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
55#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
56
57#define OSC_FREQ_DET 0x58
58#define OSC_FREQ_DET_TRIG (1<<31)
59
60#define OSC_FREQ_DET_STATUS 0x5C
61#define OSC_FREQ_DET_BUSY (1<<31)
62#define OSC_FREQ_DET_CNT_MASK 0xFFFF
63
64#define PERIPH_CLK_SOURCE_I2S1 0x100
65#define PERIPH_CLK_SOURCE_EMC 0x19c
66#define PERIPH_CLK_SOURCE_OSC 0x1fc
67#define PERIPH_CLK_SOURCE_NUM \
68 ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
69
70#define PERIPH_CLK_SOURCE_MASK (3<<30)
71#define PERIPH_CLK_SOURCE_SHIFT 30
72#define PERIPH_CLK_SOURCE_PWM_MASK (7<<28)
73#define PERIPH_CLK_SOURCE_PWM_SHIFT 28
74#define PERIPH_CLK_SOURCE_ENABLE (1<<28)
75#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
76#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
77#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
78
79#define SDMMC_CLK_INT_FB_SEL (1 << 23)
80#define SDMMC_CLK_INT_FB_DLY_SHIFT 16
81#define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
82
83#define PLL_BASE 0x0
84#define PLL_BASE_BYPASS (1<<31)
85#define PLL_BASE_ENABLE (1<<30)
86#define PLL_BASE_REF_ENABLE (1<<29)
87#define PLL_BASE_OVERRIDE (1<<28)
88#define PLL_BASE_DIVP_MASK (0x7<<20)
89#define PLL_BASE_DIVP_SHIFT 20
90#define PLL_BASE_DIVN_MASK (0x3FF<<8)
91#define PLL_BASE_DIVN_SHIFT 8
92#define PLL_BASE_DIVM_MASK (0x1F)
93#define PLL_BASE_DIVM_SHIFT 0
94
95#define PLL_OUT_RATIO_MASK (0xFF<<8)
96#define PLL_OUT_RATIO_SHIFT 8
97#define PLL_OUT_OVERRIDE (1<<2)
98#define PLL_OUT_CLKEN (1<<1)
99#define PLL_OUT_RESET_DISABLE (1<<0)
100
101#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
102
103#define PLL_MISC_DCCON_SHIFT 20
104#define PLL_MISC_CPCON_SHIFT 8
105#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
106#define PLL_MISC_LFCON_SHIFT 4
107#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
108#define PLL_MISC_VCOCON_SHIFT 0
109#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
110
111#define PLLU_BASE_POST_DIV (1<<20)
112
113#define PLLD_MISC_CLKENABLE (1<<30)
114#define PLLD_MISC_DIV_RST (1<<23)
115#define PLLD_MISC_DCCON_SHIFT 12
116
117#define PLLE_MISC_READY (1 << 15)
118
119#define PERIPH_CLK_TO_ENB_REG(c) ((c->u.periph.clk_num / 32) * 4)
120#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8)
121#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32))
122
123#define SUPER_CLK_MUX 0x00
124#define SUPER_STATE_SHIFT 28
125#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
126#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
127#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
128#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
129#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
130#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
131#define SUPER_SOURCE_MASK 0xF
132#define SUPER_FIQ_SOURCE_SHIFT 12
133#define SUPER_IRQ_SOURCE_SHIFT 8
134#define SUPER_RUN_SOURCE_SHIFT 4
135#define SUPER_IDLE_SOURCE_SHIFT 0
136
137#define SUPER_CLK_DIVIDER 0x04
138
139#define BUS_CLK_DISABLE (1<<3)
140#define BUS_CLK_DIV_MASK 0x3
141
142#define PMC_CTRL 0x0
143 #define PMC_CTRL_BLINK_ENB (1 << 7)
144
145#define PMC_DPD_PADS_ORIDE 0x1c
146 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
147
148#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
149#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
150#define PMC_BLINK_TIMER_ENB (1 << 15)
151#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
152#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
153
154/* Tegra CPU clock and reset control regs */
155#define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c
156#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340
157#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344
158
159#define CPU_CLOCK(cpu) (0x1 << (8 + cpu))
160#define CPU_RESET(cpu) (0x1111ul << (cpu))
161
162static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
163static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
164
165/*
166 * Some clocks share a register with other clocks. Any clock op that
167 * non-atomically modifies a register used by another clock must lock
168 * clock_register_lock first.
169 */
170static DEFINE_SPINLOCK(clock_register_lock);
171
172/*
173 * Some peripheral clocks share an enable bit, so refcount the enable bits
174 * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U
175 */
176static int tegra_periph_clk_enable_refcount[3 * 32];
177
178#define clk_writel(value, reg) \
179 __raw_writel(value, reg_clk_base + (reg))
180#define clk_readl(reg) \
181 __raw_readl(reg_clk_base + (reg))
182#define pmc_writel(value, reg) \
183 __raw_writel(value, reg_pmc_base + (reg))
184#define pmc_readl(reg) \
185 __raw_readl(reg_pmc_base + (reg))
186
187static unsigned long clk_measure_input_freq(void)
188{
189 u32 clock_autodetect;
190 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
191 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
192 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
193 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
194 return 12000000;
195 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
196 return 13000000;
197 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
198 return 19200000;
199 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
200 return 26000000;
201 } else {
202 pr_err("%s: Unexpected clock autodetect value %d",
203 __func__, clock_autodetect);
204 BUG();
205 return 0;
206 }
207}
208
209static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
210{
211 s64 divider_u71 = parent_rate * 2;
212 divider_u71 += rate - 1;
213 do_div(divider_u71, rate);
214
215 if (divider_u71 - 2 < 0)
216 return 0;
217
218 if (divider_u71 - 2 > 255)
219 return -EINVAL;
220
221 return divider_u71 - 2;
222}
223
224static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
225{
226 s64 divider_u16;
227
228 divider_u16 = parent_rate;
229 divider_u16 += rate - 1;
230 do_div(divider_u16, rate);
231
232 if (divider_u16 - 1 < 0)
233 return 0;
234
235 if (divider_u16 - 1 > 0xFFFF)
236 return -EINVAL;
237
238 return divider_u16 - 1;
239}
240
241static unsigned long tegra_clk_fixed_recalc_rate(struct clk_hw *hw,
242 unsigned long parent_rate)
243{
244 return to_clk_tegra(hw)->fixed_rate;
245}
246
247struct clk_ops tegra_clk_32k_ops = {
248 .recalc_rate = tegra_clk_fixed_recalc_rate,
249};
250
251/* clk_m functions */
252static unsigned long tegra20_clk_m_recalc_rate(struct clk_hw *hw,
253 unsigned long prate)
254{
255 if (!to_clk_tegra(hw)->fixed_rate)
256 to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq();
257 return to_clk_tegra(hw)->fixed_rate;
258}
259
260static void tegra20_clk_m_init(struct clk_hw *hw)
261{
262 struct clk_tegra *c = to_clk_tegra(hw);
263 u32 osc_ctrl = clk_readl(OSC_CTRL);
264 u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
265
266 switch (c->fixed_rate) {
267 case 12000000:
268 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
269 break;
270 case 13000000:
271 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
272 break;
273 case 19200000:
274 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
275 break;
276 case 26000000:
277 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
278 break;
279 default:
280 BUG();
281 }
282 clk_writel(auto_clock_control, OSC_CTRL);
283}
284
285struct clk_ops tegra_clk_m_ops = {
286 .init = tegra20_clk_m_init,
287 .recalc_rate = tegra20_clk_m_recalc_rate,
288};
289
290/* super clock functions */
291/* "super clocks" on tegra have two-stage muxes and a clock skipping
292 * super divider. We will ignore the clock skipping divider, since we
293 * can't lower the voltage when using the clock skip, but we can if we
294 * lower the PLL frequency.
295 */
296static int tegra20_super_clk_is_enabled(struct clk_hw *hw)
297{
298 struct clk_tegra *c = to_clk_tegra(hw);
299 u32 val;
300
301 val = clk_readl(c->reg + SUPER_CLK_MUX);
302 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
303 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
304 c->state = ON;
305 return c->state;
306}
307
308static int tegra20_super_clk_enable(struct clk_hw *hw)
309{
310 struct clk_tegra *c = to_clk_tegra(hw);
311 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
312 return 0;
313}
314
315static void tegra20_super_clk_disable(struct clk_hw *hw)
316{
317 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
318
319 /* oops - don't disable the CPU clock! */
320 BUG();
321}
322
323static u8 tegra20_super_clk_get_parent(struct clk_hw *hw)
324{
325 struct clk_tegra *c = to_clk_tegra(hw);
326 int val = clk_readl(c->reg + SUPER_CLK_MUX);
327 int source;
328 int shift;
329
330 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
331 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
332 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
333 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
334 source = (val >> shift) & SUPER_SOURCE_MASK;
335 return source;
336}
337
338static int tegra20_super_clk_set_parent(struct clk_hw *hw, u8 index)
339{
340 struct clk_tegra *c = to_clk_tegra(hw);
341 u32 val = clk_readl(c->reg + SUPER_CLK_MUX);
342 int shift;
343
344 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
345 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
346 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
347 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
348 val &= ~(SUPER_SOURCE_MASK << shift);
349 val |= index << shift;
350
351 clk_writel(val, c->reg);
352
353 return 0;
354}
355
356/* FIX ME: Need to switch parents to change the source PLL rate */
357static unsigned long tegra20_super_clk_recalc_rate(struct clk_hw *hw,
358 unsigned long prate)
359{
360 return prate;
361}
362
363static long tegra20_super_clk_round_rate(struct clk_hw *hw, unsigned long rate,
364 unsigned long *prate)
365{
366 return *prate;
367}
368
369static int tegra20_super_clk_set_rate(struct clk_hw *hw, unsigned long rate,
370 unsigned long parent_rate)
371{
372 return 0;
373}
374
375struct clk_ops tegra_super_ops = {
376 .is_enabled = tegra20_super_clk_is_enabled,
377 .enable = tegra20_super_clk_enable,
378 .disable = tegra20_super_clk_disable,
379 .set_parent = tegra20_super_clk_set_parent,
380 .get_parent = tegra20_super_clk_get_parent,
381 .set_rate = tegra20_super_clk_set_rate,
382 .round_rate = tegra20_super_clk_round_rate,
383 .recalc_rate = tegra20_super_clk_recalc_rate,
384};
385
386static unsigned long tegra20_twd_clk_recalc_rate(struct clk_hw *hw,
387 unsigned long parent_rate)
388{
389 struct clk_tegra *c = to_clk_tegra(hw);
390 u64 rate = parent_rate;
391
392 if (c->mul != 0 && c->div != 0) {
393 rate *= c->mul;
394 rate += c->div - 1; /* round up */
395 do_div(rate, c->div);
396 }
397
398 return rate;
399}
400
401struct clk_ops tegra_twd_ops = {
402 .recalc_rate = tegra20_twd_clk_recalc_rate,
403};
404
405static u8 tegra20_cop_clk_get_parent(struct clk_hw *hw)
406{
407 return 0;
408}
409
410struct clk_ops tegra_cop_ops = {
411 .get_parent = tegra20_cop_clk_get_parent,
412};
413
414/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
415 * reset the COP block (i.e. AVP) */
416void tegra2_cop_clk_reset(struct clk_hw *hw, bool assert)
417{
418 unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
419
420 pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
421 clk_writel(1 << 1, reg);
422}
423
424/* bus clock functions */
425static int tegra20_bus_clk_is_enabled(struct clk_hw *hw)
426{
427 struct clk_tegra *c = to_clk_tegra(hw);
428 u32 val = clk_readl(c->reg);
429
430 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
431 return c->state;
432}
433
434static int tegra20_bus_clk_enable(struct clk_hw *hw)
435{
436 struct clk_tegra *c = to_clk_tegra(hw);
437 unsigned long flags;
438 u32 val;
439
440 spin_lock_irqsave(&clock_register_lock, flags);
441
442 val = clk_readl(c->reg);
443 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
444 clk_writel(val, c->reg);
445
446 spin_unlock_irqrestore(&clock_register_lock, flags);
447
448 return 0;
449}
450
451static void tegra20_bus_clk_disable(struct clk_hw *hw)
452{
453 struct clk_tegra *c = to_clk_tegra(hw);
454 unsigned long flags;
455 u32 val;
456
457 spin_lock_irqsave(&clock_register_lock, flags);
458
459 val = clk_readl(c->reg);
460 val |= BUS_CLK_DISABLE << c->reg_shift;
461 clk_writel(val, c->reg);
462
463 spin_unlock_irqrestore(&clock_register_lock, flags);
464}
465
466static unsigned long tegra20_bus_clk_recalc_rate(struct clk_hw *hw,
467 unsigned long prate)
468{
469 struct clk_tegra *c = to_clk_tegra(hw);
470 u32 val = clk_readl(c->reg);
471 u64 rate = prate;
472
473 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
474 c->mul = 1;
475
476 if (c->mul != 0 && c->div != 0) {
477 rate *= c->mul;
478 rate += c->div - 1; /* round up */
479 do_div(rate, c->div);
480 }
481 return rate;
482}
483
484static int tegra20_bus_clk_set_rate(struct clk_hw *hw, unsigned long rate,
485 unsigned long parent_rate)
486{
487 struct clk_tegra *c = to_clk_tegra(hw);
488 int ret = -EINVAL;
489 unsigned long flags;
490 u32 val;
491 int i;
492
493 spin_lock_irqsave(&clock_register_lock, flags);
494
495 val = clk_readl(c->reg);
496 for (i = 1; i <= 4; i++) {
497 if (rate == parent_rate / i) {
498 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
499 val |= (i - 1) << c->reg_shift;
500 clk_writel(val, c->reg);
501 c->div = i;
502 c->mul = 1;
503 ret = 0;
504 break;
505 }
506 }
507
508 spin_unlock_irqrestore(&clock_register_lock, flags);
509
510 return ret;
511}
512
513static long tegra20_bus_clk_round_rate(struct clk_hw *hw, unsigned long rate,
514 unsigned long *prate)
515{
516 unsigned long parent_rate = *prate;
517 s64 divider;
518
519 if (rate >= parent_rate)
520 return rate;
521
522 divider = parent_rate;
523 divider += rate - 1;
524 do_div(divider, rate);
525
526 if (divider < 0)
527 return divider;
528
529 if (divider > 4)
530 divider = 4;
531 do_div(parent_rate, divider);
532
533 return parent_rate;
534}
535
536struct clk_ops tegra_bus_ops = {
537 .is_enabled = tegra20_bus_clk_is_enabled,
538 .enable = tegra20_bus_clk_enable,
539 .disable = tegra20_bus_clk_disable,
540 .set_rate = tegra20_bus_clk_set_rate,
541 .round_rate = tegra20_bus_clk_round_rate,
542 .recalc_rate = tegra20_bus_clk_recalc_rate,
543};
544
545/* Blink output functions */
546static int tegra20_blink_clk_is_enabled(struct clk_hw *hw)
547{
548 struct clk_tegra *c = to_clk_tegra(hw);
549 u32 val;
550
551 val = pmc_readl(PMC_CTRL);
552 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
553 return c->state;
554}
555
556static unsigned long tegra20_blink_clk_recalc_rate(struct clk_hw *hw,
557 unsigned long prate)
558{
559 struct clk_tegra *c = to_clk_tegra(hw);
560 u64 rate = prate;
561 u32 val;
562
563 c->mul = 1;
564 val = pmc_readl(c->reg);
565
566 if (val & PMC_BLINK_TIMER_ENB) {
567 unsigned int on_off;
568
569 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
570 PMC_BLINK_TIMER_DATA_ON_MASK;
571 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
572 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
573 on_off += val;
574 /* each tick in the blink timer is 4 32KHz clocks */
575 c->div = on_off * 4;
576 } else {
577 c->div = 1;
578 }
579
580 if (c->mul != 0 && c->div != 0) {
581 rate *= c->mul;
582 rate += c->div - 1; /* round up */
583 do_div(rate, c->div);
584 }
585 return rate;
586}
587
588static int tegra20_blink_clk_enable(struct clk_hw *hw)
589{
590 u32 val;
591
592 val = pmc_readl(PMC_DPD_PADS_ORIDE);
593 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
594
595 val = pmc_readl(PMC_CTRL);
596 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
597
598 return 0;
599}
600
601static void tegra20_blink_clk_disable(struct clk_hw *hw)
602{
603 u32 val;
604
605 val = pmc_readl(PMC_CTRL);
606 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
607
608 val = pmc_readl(PMC_DPD_PADS_ORIDE);
609 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
610}
611
612static int tegra20_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate,
613 unsigned long parent_rate)
614{
615 struct clk_tegra *c = to_clk_tegra(hw);
616
617 if (rate >= parent_rate) {
618 c->div = 1;
619 pmc_writel(0, c->reg);
620 } else {
621 unsigned int on_off;
622 u32 val;
623
624 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
625 c->div = on_off * 8;
626
627 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
628 PMC_BLINK_TIMER_DATA_ON_SHIFT;
629 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
630 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
631 val |= on_off;
632 val |= PMC_BLINK_TIMER_ENB;
633 pmc_writel(val, c->reg);
634 }
635
636 return 0;
637}
638
639static long tegra20_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate,
640 unsigned long *prate)
641{
642 int div;
643 int mul;
644 long round_rate = *prate;
645
646 mul = 1;
647
648 if (rate >= *prate) {
649 div = 1;
650 } else {
651 div = DIV_ROUND_UP(*prate / 8, rate);
652 div *= 8;
653 }
654
655 round_rate *= mul;
656 round_rate += div - 1;
657 do_div(round_rate, div);
658
659 return round_rate;
660}
661
662struct clk_ops tegra_blink_clk_ops = {
663 .is_enabled = tegra20_blink_clk_is_enabled,
664 .enable = tegra20_blink_clk_enable,
665 .disable = tegra20_blink_clk_disable,
666 .set_rate = tegra20_blink_clk_set_rate,
667 .round_rate = tegra20_blink_clk_round_rate,
668 .recalc_rate = tegra20_blink_clk_recalc_rate,
669};
670
671/* PLL Functions */
672static int tegra20_pll_clk_wait_for_lock(struct clk_tegra *c)
673{
674 udelay(c->u.pll.lock_delay);
675 return 0;
676}
677
678static int tegra20_pll_clk_is_enabled(struct clk_hw *hw)
679{
680 struct clk_tegra *c = to_clk_tegra(hw);
681 u32 val = clk_readl(c->reg + PLL_BASE);
682
683 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
684 return c->state;
685}
686
687static unsigned long tegra20_pll_clk_recalc_rate(struct clk_hw *hw,
688 unsigned long prate)
689{
690 struct clk_tegra *c = to_clk_tegra(hw);
691 u32 val = clk_readl(c->reg + PLL_BASE);
692 u64 rate = prate;
693
694 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
695 const struct clk_pll_freq_table *sel;
696 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
697 if (sel->input_rate == prate &&
698 sel->output_rate == c->u.pll.fixed_rate) {
699 c->mul = sel->n;
700 c->div = sel->m * sel->p;
701 break;
702 }
703 }
704 pr_err("Clock %s has unknown fixed frequency\n",
705 __clk_get_name(hw->clk));
706 BUG();
707 } else if (val & PLL_BASE_BYPASS) {
708 c->mul = 1;
709 c->div = 1;
710 } else {
711 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
712 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
713 if (c->flags & PLLU)
714 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
715 else
716 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
717 }
718
719 if (c->mul != 0 && c->div != 0) {
720 rate *= c->mul;
721 rate += c->div - 1; /* round up */
722 do_div(rate, c->div);
723 }
724 return rate;
725}
726
727static int tegra20_pll_clk_enable(struct clk_hw *hw)
728{
729 struct clk_tegra *c = to_clk_tegra(hw);
730 u32 val;
731 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
732
733 val = clk_readl(c->reg + PLL_BASE);
734 val &= ~PLL_BASE_BYPASS;
735 val |= PLL_BASE_ENABLE;
736 clk_writel(val, c->reg + PLL_BASE);
737
738 tegra20_pll_clk_wait_for_lock(c);
739
740 return 0;
741}
742
743static void tegra20_pll_clk_disable(struct clk_hw *hw)
744{
745 struct clk_tegra *c = to_clk_tegra(hw);
746 u32 val;
747 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
748
749 val = clk_readl(c->reg);
750 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
751 clk_writel(val, c->reg);
752}
753
754static int tegra20_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
755 unsigned long parent_rate)
756{
757 struct clk_tegra *c = to_clk_tegra(hw);
758 unsigned long input_rate = parent_rate;
759 const struct clk_pll_freq_table *sel;
760 u32 val;
761
762 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
763
764 if (c->flags & PLL_FIXED) {
765 int ret = 0;
766 if (rate != c->u.pll.fixed_rate) {
767 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
768 __func__, __clk_get_name(hw->clk),
769 c->u.pll.fixed_rate, rate);
770 ret = -EINVAL;
771 }
772 return ret;
773 }
774
775 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
776 if (sel->input_rate == input_rate && sel->output_rate == rate) {
777 c->mul = sel->n;
778 c->div = sel->m * sel->p;
779
780 val = clk_readl(c->reg + PLL_BASE);
781 if (c->flags & PLL_FIXED)
782 val |= PLL_BASE_OVERRIDE;
783 val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
784 PLL_BASE_DIVM_MASK);
785 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
786 (sel->n << PLL_BASE_DIVN_SHIFT);
787 BUG_ON(sel->p < 1 || sel->p > 2);
788 if (c->flags & PLLU) {
789 if (sel->p == 1)
790 val |= PLLU_BASE_POST_DIV;
791 } else {
792 if (sel->p == 2)
793 val |= 1 << PLL_BASE_DIVP_SHIFT;
794 }
795 clk_writel(val, c->reg + PLL_BASE);
796
797 if (c->flags & PLL_HAS_CPCON) {
798 val = clk_readl(c->reg + PLL_MISC(c));
799 val &= ~PLL_MISC_CPCON_MASK;
800 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
801 clk_writel(val, c->reg + PLL_MISC(c));
802 }
803
804 if (c->state == ON)
805 tegra20_pll_clk_enable(hw);
806 return 0;
807 }
808 }
809 return -EINVAL;
810}
811
812static long tegra20_pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
813 unsigned long *prate)
814{
815 struct clk_tegra *c = to_clk_tegra(hw);
816 const struct clk_pll_freq_table *sel;
817 unsigned long input_rate = *prate;
818 u64 output_rate = *prate;
819 int mul;
820 int div;
821
822 if (c->flags & PLL_FIXED)
823 return c->u.pll.fixed_rate;
824
825 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++)
826 if (sel->input_rate == input_rate && sel->output_rate == rate) {
827 mul = sel->n;
828 div = sel->m * sel->p;
829 break;
830 }
831
832 if (sel->input_rate == 0)
833 return -EINVAL;
834
835 output_rate *= mul;
836 output_rate += div - 1; /* round up */
837 do_div(output_rate, div);
838
839 return output_rate;
840}
841
842struct clk_ops tegra_pll_ops = {
843 .is_enabled = tegra20_pll_clk_is_enabled,
844 .enable = tegra20_pll_clk_enable,
845 .disable = tegra20_pll_clk_disable,
846 .set_rate = tegra20_pll_clk_set_rate,
847 .recalc_rate = tegra20_pll_clk_recalc_rate,
848 .round_rate = tegra20_pll_clk_round_rate,
849};
850
851static void tegra20_pllx_clk_init(struct clk_hw *hw)
852{
853 struct clk_tegra *c = to_clk_tegra(hw);
854
855 if (tegra_sku_id == 7)
856 c->max_rate = 750000000;
857}
858
859struct clk_ops tegra_pllx_ops = {
860 .init = tegra20_pllx_clk_init,
861 .is_enabled = tegra20_pll_clk_is_enabled,
862 .enable = tegra20_pll_clk_enable,
863 .disable = tegra20_pll_clk_disable,
864 .set_rate = tegra20_pll_clk_set_rate,
865 .recalc_rate = tegra20_pll_clk_recalc_rate,
866 .round_rate = tegra20_pll_clk_round_rate,
867};
868
869static int tegra20_plle_clk_enable(struct clk_hw *hw)
870{
871 struct clk_tegra *c = to_clk_tegra(hw);
872 u32 val;
873
874 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
875
876 mdelay(1);
877
878 val = clk_readl(c->reg + PLL_BASE);
879 if (!(val & PLLE_MISC_READY))
880 return -EBUSY;
881
882 val = clk_readl(c->reg + PLL_BASE);
883 val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
884 clk_writel(val, c->reg + PLL_BASE);
885
886 return 0;
887}
888
889struct clk_ops tegra_plle_ops = {
890 .is_enabled = tegra20_pll_clk_is_enabled,
891 .enable = tegra20_plle_clk_enable,
892 .set_rate = tegra20_pll_clk_set_rate,
893 .recalc_rate = tegra20_pll_clk_recalc_rate,
894 .round_rate = tegra20_pll_clk_round_rate,
895};
896
897/* Clock divider ops */
898static int tegra20_pll_div_clk_is_enabled(struct clk_hw *hw)
899{
900 struct clk_tegra *c = to_clk_tegra(hw);
901 u32 val = clk_readl(c->reg);
902
903 val >>= c->reg_shift;
904 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
905 if (!(val & PLL_OUT_RESET_DISABLE))
906 c->state = OFF;
907 return c->state;
908}
909
910static unsigned long tegra20_pll_div_clk_recalc_rate(struct clk_hw *hw,
911 unsigned long prate)
912{
913 struct clk_tegra *c = to_clk_tegra(hw);
914 u64 rate = prate;
915 u32 val = clk_readl(c->reg);
916 u32 divu71;
917
918 val >>= c->reg_shift;
919
920 if (c->flags & DIV_U71) {
921 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
922 c->div = (divu71 + 2);
923 c->mul = 2;
924 } else if (c->flags & DIV_2) {
925 c->div = 2;
926 c->mul = 1;
927 } else {
928 c->div = 1;
929 c->mul = 1;
930 }
931
932 rate *= c->mul;
933 rate += c->div - 1; /* round up */
934 do_div(rate, c->div);
935
936 return rate;
937}
938
939static int tegra20_pll_div_clk_enable(struct clk_hw *hw)
940{
941 struct clk_tegra *c = to_clk_tegra(hw);
942 unsigned long flags;
943 u32 new_val;
944 u32 val;
945
946 pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
947
948 if (c->flags & DIV_U71) {
949 spin_lock_irqsave(&clock_register_lock, flags);
950 val = clk_readl(c->reg);
951 new_val = val >> c->reg_shift;
952 new_val &= 0xFFFF;
953
954 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
955
956 val &= ~(0xFFFF << c->reg_shift);
957 val |= new_val << c->reg_shift;
958 clk_writel(val, c->reg);
959 spin_unlock_irqrestore(&clock_register_lock, flags);
960 return 0;
961 } else if (c->flags & DIV_2) {
962 BUG_ON(!(c->flags & PLLD));
963 spin_lock_irqsave(&clock_register_lock, flags);
964 val = clk_readl(c->reg);
965 val &= ~PLLD_MISC_DIV_RST;
966 clk_writel(val, c->reg);
967 spin_unlock_irqrestore(&clock_register_lock, flags);
968 return 0;
969 }
970 return -EINVAL;
971}
972
973static void tegra20_pll_div_clk_disable(struct clk_hw *hw)
974{
975 struct clk_tegra *c = to_clk_tegra(hw);
976 unsigned long flags;
977 u32 new_val;
978 u32 val;
979
980 pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
981
982 if (c->flags & DIV_U71) {
983 spin_lock_irqsave(&clock_register_lock, flags);
984 val = clk_readl(c->reg);
985 new_val = val >> c->reg_shift;
986 new_val &= 0xFFFF;
987
988 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
989
990 val &= ~(0xFFFF << c->reg_shift);
991 val |= new_val << c->reg_shift;
992 clk_writel(val, c->reg);
993 spin_unlock_irqrestore(&clock_register_lock, flags);
994 } else if (c->flags & DIV_2) {
995 BUG_ON(!(c->flags & PLLD));
996 spin_lock_irqsave(&clock_register_lock, flags);
997 val = clk_readl(c->reg);
998 val |= PLLD_MISC_DIV_RST;
999 clk_writel(val, c->reg);
1000 spin_unlock_irqrestore(&clock_register_lock, flags);
1001 }
1002}
1003
1004static int tegra20_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1005 unsigned long parent_rate)
1006{
1007 struct clk_tegra *c = to_clk_tegra(hw);
1008 unsigned long flags;
1009 int divider_u71;
1010 u32 new_val;
1011 u32 val;
1012
1013 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
1014
1015 if (c->flags & DIV_U71) {
1016 divider_u71 = clk_div71_get_divider(parent_rate, rate);
1017 if (divider_u71 >= 0) {
1018 spin_lock_irqsave(&clock_register_lock, flags);
1019 val = clk_readl(c->reg);
1020 new_val = val >> c->reg_shift;
1021 new_val &= 0xFFFF;
1022 if (c->flags & DIV_U71_FIXED)
1023 new_val |= PLL_OUT_OVERRIDE;
1024 new_val &= ~PLL_OUT_RATIO_MASK;
1025 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
1026
1027 val &= ~(0xFFFF << c->reg_shift);
1028 val |= new_val << c->reg_shift;
1029 clk_writel(val, c->reg);
1030 c->div = divider_u71 + 2;
1031 c->mul = 2;
1032 spin_unlock_irqrestore(&clock_register_lock, flags);
1033 return 0;
1034 }
1035 } else if (c->flags & DIV_2) {
1036 if (parent_rate == rate * 2)
1037 return 0;
1038 }
1039 return -EINVAL;
1040}
1041
1042static long tegra20_pll_div_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1043 unsigned long *prate)
1044{
1045 struct clk_tegra *c = to_clk_tegra(hw);
1046 unsigned long parent_rate = *prate;
1047 int divider;
1048
1049 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
1050
1051 if (c->flags & DIV_U71) {
1052 divider = clk_div71_get_divider(parent_rate, rate);
1053 if (divider < 0)
1054 return divider;
1055 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1056 } else if (c->flags & DIV_2) {
1057 return DIV_ROUND_UP(parent_rate, 2);
1058 }
1059 return -EINVAL;
1060}
1061
1062struct clk_ops tegra_pll_div_ops = {
1063 .is_enabled = tegra20_pll_div_clk_is_enabled,
1064 .enable = tegra20_pll_div_clk_enable,
1065 .disable = tegra20_pll_div_clk_disable,
1066 .set_rate = tegra20_pll_div_clk_set_rate,
1067 .round_rate = tegra20_pll_div_clk_round_rate,
1068 .recalc_rate = tegra20_pll_div_clk_recalc_rate,
1069};
1070
1071/* Periph clk ops */
1072
1073static int tegra20_periph_clk_is_enabled(struct clk_hw *hw)
1074{
1075 struct clk_tegra *c = to_clk_tegra(hw);
1076
1077 c->state = ON;
1078
1079 if (!c->u.periph.clk_num)
1080 goto out;
1081
1082 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1083 PERIPH_CLK_TO_ENB_BIT(c)))
1084 c->state = OFF;
1085
1086 if (!(c->flags & PERIPH_NO_RESET))
1087 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
1088 PERIPH_CLK_TO_ENB_BIT(c))
1089 c->state = OFF;
1090
1091out:
1092 return c->state;
1093}
1094
1095static int tegra20_periph_clk_enable(struct clk_hw *hw)
1096{
1097 struct clk_tegra *c = to_clk_tegra(hw);
1098 unsigned long flags;
1099 u32 val;
1100
1101 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
1102
1103 if (!c->u.periph.clk_num)
1104 return 0;
1105
1106 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
1107 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
1108 return 0;
1109
1110 spin_lock_irqsave(&clock_register_lock, flags);
1111
1112 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1113 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1114 if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
1115 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1116 RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1117 if (c->flags & PERIPH_EMC_ENB) {
1118 /* The EMC peripheral clock has 2 extra enable bits */
1119 /* FIXME: Do they need to be disabled? */
1120 val = clk_readl(c->reg);
1121 val |= 0x3 << 24;
1122 clk_writel(val, c->reg);
1123 }
1124
1125 spin_unlock_irqrestore(&clock_register_lock, flags);
1126
1127 return 0;
1128}
1129
1130static void tegra20_periph_clk_disable(struct clk_hw *hw)
1131{
1132 struct clk_tegra *c = to_clk_tegra(hw);
1133 unsigned long flags;
1134
1135 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
1136
1137 if (!c->u.periph.clk_num)
1138 return;
1139
1140 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
1141
1142 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0)
1143 return;
1144
1145 spin_lock_irqsave(&clock_register_lock, flags);
1146
1147 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1148 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1149
1150 spin_unlock_irqrestore(&clock_register_lock, flags);
1151}
1152
1153void tegra2_periph_clk_reset(struct clk_hw *hw, bool assert)
1154{
1155 struct clk_tegra *c = to_clk_tegra(hw);
1156 unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
1157
1158 pr_debug("%s %s on clock %s\n", __func__,
1159 assert ? "assert" : "deassert", __clk_get_name(hw->clk));
1160
1161 BUG_ON(!c->u.periph.clk_num);
1162
1163 if (!(c->flags & PERIPH_NO_RESET))
1164 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1165 base + PERIPH_CLK_TO_ENB_SET_REG(c));
1166}
1167
1168static int tegra20_periph_clk_set_parent(struct clk_hw *hw, u8 index)
1169{
1170 struct clk_tegra *c = to_clk_tegra(hw);
1171 u32 val;
1172 u32 mask;
1173 u32 shift;
1174
1175 pr_debug("%s: %s %d\n", __func__, __clk_get_name(hw->clk), index);
1176
1177 if (c->flags & MUX_PWM) {
1178 shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
1179 mask = PERIPH_CLK_SOURCE_PWM_MASK;
1180 } else {
1181 shift = PERIPH_CLK_SOURCE_SHIFT;
1182 mask = PERIPH_CLK_SOURCE_MASK;
1183 }
1184
1185 val = clk_readl(c->reg);
1186 val &= ~mask;
1187 val |= (index) << shift;
1188
1189 clk_writel(val, c->reg);
1190
1191 return 0;
1192}
1193
1194static u8 tegra20_periph_clk_get_parent(struct clk_hw *hw)
1195{
1196 struct clk_tegra *c = to_clk_tegra(hw);
1197 u32 val = clk_readl(c->reg);
1198 u32 mask;
1199 u32 shift;
1200
1201 if (c->flags & MUX_PWM) {
1202 shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
1203 mask = PERIPH_CLK_SOURCE_PWM_MASK;
1204 } else {
1205 shift = PERIPH_CLK_SOURCE_SHIFT;
1206 mask = PERIPH_CLK_SOURCE_MASK;
1207 }
1208
1209 if (c->flags & MUX)
1210 return (val & mask) >> shift;
1211 else
1212 return 0;
1213}
1214
1215static unsigned long tegra20_periph_clk_recalc_rate(struct clk_hw *hw,
1216 unsigned long prate)
1217{
1218 struct clk_tegra *c = to_clk_tegra(hw);
1219 unsigned long rate = prate;
1220 u32 val = clk_readl(c->reg);
1221
1222 if (c->flags & DIV_U71) {
1223 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
1224 c->div = divu71 + 2;
1225 c->mul = 2;
1226 } else if (c->flags & DIV_U16) {
1227 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
1228 c->div = divu16 + 1;
1229 c->mul = 1;
1230 } else {
1231 c->div = 1;
1232 c->mul = 1;
1233 return rate;
1234 }
1235
1236 if (c->mul != 0 && c->div != 0) {
1237 rate *= c->mul;
1238 rate += c->div - 1; /* round up */
1239 do_div(rate, c->div);
1240 }
1241
1242 return rate;
1243}
1244
1245static int tegra20_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1246 unsigned long parent_rate)
1247{
1248 struct clk_tegra *c = to_clk_tegra(hw);
1249 u32 val;
1250 int divider;
1251
1252 val = clk_readl(c->reg);
1253
1254 if (c->flags & DIV_U71) {
1255 divider = clk_div71_get_divider(parent_rate, rate);
1256
1257 if (divider >= 0) {
1258 val = clk_readl(c->reg);
1259 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
1260 val |= divider;
1261 clk_writel(val, c->reg);
1262 c->div = divider + 2;
1263 c->mul = 2;
1264 return 0;
1265 }
1266 } else if (c->flags & DIV_U16) {
1267 divider = clk_div16_get_divider(parent_rate, rate);
1268 if (divider >= 0) {
1269 val = clk_readl(c->reg);
1270 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
1271 val |= divider;
1272 clk_writel(val, c->reg);
1273 c->div = divider + 1;
1274 c->mul = 1;
1275 return 0;
1276 }
1277 } else if (parent_rate <= rate) {
1278 c->div = 1;
1279 c->mul = 1;
1280 return 0;
1281 }
1282
1283 return -EINVAL;
1284}
1285
1286static long tegra20_periph_clk_round_rate(struct clk_hw *hw,
1287 unsigned long rate, unsigned long *prate)
1288{
1289 struct clk_tegra *c = to_clk_tegra(hw);
1290 unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
1291 int divider;
1292
1293 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
1294
1295 if (prate)
1296 parent_rate = *prate;
1297
1298 if (c->flags & DIV_U71) {
1299 divider = clk_div71_get_divider(parent_rate, rate);
1300 if (divider < 0)
1301 return divider;
1302
1303 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1304 } else if (c->flags & DIV_U16) {
1305 divider = clk_div16_get_divider(parent_rate, rate);
1306 if (divider < 0)
1307 return divider;
1308 return DIV_ROUND_UP(parent_rate, divider + 1);
1309 }
1310 return -EINVAL;
1311}
1312
1313struct clk_ops tegra_periph_clk_ops = {
1314 .is_enabled = tegra20_periph_clk_is_enabled,
1315 .enable = tegra20_periph_clk_enable,
1316 .disable = tegra20_periph_clk_disable,
1317 .set_parent = tegra20_periph_clk_set_parent,
1318 .get_parent = tegra20_periph_clk_get_parent,
1319 .set_rate = tegra20_periph_clk_set_rate,
1320 .round_rate = tegra20_periph_clk_round_rate,
1321 .recalc_rate = tegra20_periph_clk_recalc_rate,
1322};
1323
1324/* External memory controller clock ops */
1325static void tegra20_emc_clk_init(struct clk_hw *hw)
1326{
1327 struct clk_tegra *c = to_clk_tegra(hw);
1328 c->max_rate = __clk_get_rate(hw->clk);
1329}
1330
1331static long tegra20_emc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1332 unsigned long *prate)
1333{
1334 struct clk_tegra *c = to_clk_tegra(hw);
1335 long emc_rate;
1336 long clk_rate;
1337
1338 /*
1339 * The slowest entry in the EMC clock table that is at least as
1340 * fast as rate.
1341 */
1342 emc_rate = tegra_emc_round_rate(rate);
1343 if (emc_rate < 0)
1344 return c->max_rate;
1345
1346 /*
1347 * The fastest rate the PLL will generate that is at most the
1348 * requested rate.
1349 */
1350 clk_rate = tegra20_periph_clk_round_rate(hw, emc_rate, NULL);
1351
1352 /*
1353 * If this fails, and emc_rate > clk_rate, it's because the maximum
1354 * rate in the EMC tables is larger than the maximum rate of the EMC
1355 * clock. The EMC clock's max rate is the rate it was running when the
1356 * kernel booted. Such a mismatch is probably due to using the wrong
1357 * BCT, i.e. using a Tegra20 BCT with an EMC table written for Tegra25.
1358 */
1359 WARN_ONCE(emc_rate != clk_rate,
1360 "emc_rate %ld != clk_rate %ld",
1361 emc_rate, clk_rate);
1362
1363 return emc_rate;
1364}
1365
1366static int tegra20_emc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1367 unsigned long parent_rate)
1368{
1369 int ret;
1370
1371 /*
1372 * The Tegra2 memory controller has an interlock with the clock
1373 * block that allows memory shadowed registers to be updated,
1374 * and then transfer them to the main registers at the same
1375 * time as the clock update without glitches.
1376 */
1377 ret = tegra_emc_set_rate(rate);
1378 if (ret < 0)
1379 return ret;
1380
1381 ret = tegra20_periph_clk_set_rate(hw, rate, parent_rate);
1382 udelay(1);
1383
1384 return ret;
1385}
1386
1387struct clk_ops tegra_emc_clk_ops = {
1388 .init = tegra20_emc_clk_init,
1389 .is_enabled = tegra20_periph_clk_is_enabled,
1390 .enable = tegra20_periph_clk_enable,
1391 .disable = tegra20_periph_clk_disable,
1392 .set_parent = tegra20_periph_clk_set_parent,
1393 .get_parent = tegra20_periph_clk_get_parent,
1394 .set_rate = tegra20_emc_clk_set_rate,
1395 .round_rate = tegra20_emc_clk_round_rate,
1396 .recalc_rate = tegra20_periph_clk_recalc_rate,
1397};
1398
1399/* Clock doubler ops */
1400static int tegra20_clk_double_is_enabled(struct clk_hw *hw)
1401{
1402 struct clk_tegra *c = to_clk_tegra(hw);
1403
1404 c->state = ON;
1405
1406 if (!c->u.periph.clk_num)
1407 goto out;
1408
1409 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1410 PERIPH_CLK_TO_ENB_BIT(c)))
1411 c->state = OFF;
1412
1413out:
1414 return c->state;
1415};
1416
1417static unsigned long tegra20_clk_double_recalc_rate(struct clk_hw *hw,
1418 unsigned long prate)
1419{
1420 struct clk_tegra *c = to_clk_tegra(hw);
1421 u64 rate = prate;
1422
1423 c->mul = 2;
1424 c->div = 1;
1425
1426 rate *= c->mul;
1427 rate += c->div - 1; /* round up */
1428 do_div(rate, c->div);
1429
1430 return rate;
1431}
1432
1433static long tegra20_clk_double_round_rate(struct clk_hw *hw, unsigned long rate,
1434 unsigned long *prate)
1435{
1436 unsigned long output_rate = *prate;
1437
1438 do_div(output_rate, 2);
1439 return output_rate;
1440}
1441
1442static int tegra20_clk_double_set_rate(struct clk_hw *hw, unsigned long rate,
1443 unsigned long parent_rate)
1444{
1445 if (rate != 2 * parent_rate)
1446 return -EINVAL;
1447 return 0;
1448}
1449
1450struct clk_ops tegra_clk_double_ops = {
1451 .is_enabled = tegra20_clk_double_is_enabled,
1452 .enable = tegra20_periph_clk_enable,
1453 .disable = tegra20_periph_clk_disable,
1454 .set_rate = tegra20_clk_double_set_rate,
1455 .recalc_rate = tegra20_clk_double_recalc_rate,
1456 .round_rate = tegra20_clk_double_round_rate,
1457};
1458
1459/* Audio sync clock ops */
1460static int tegra20_audio_sync_clk_is_enabled(struct clk_hw *hw)
1461{
1462 struct clk_tegra *c = to_clk_tegra(hw);
1463 u32 val = clk_readl(c->reg);
1464
1465 c->state = (val & (1<<4)) ? OFF : ON;
1466 return c->state;
1467}
1468
1469static int tegra20_audio_sync_clk_enable(struct clk_hw *hw)
1470{
1471 struct clk_tegra *c = to_clk_tegra(hw);
1472
1473 clk_writel(0, c->reg);
1474 return 0;
1475}
1476
1477static void tegra20_audio_sync_clk_disable(struct clk_hw *hw)
1478{
1479 struct clk_tegra *c = to_clk_tegra(hw);
1480 clk_writel(1, c->reg);
1481}
1482
1483static u8 tegra20_audio_sync_clk_get_parent(struct clk_hw *hw)
1484{
1485 struct clk_tegra *c = to_clk_tegra(hw);
1486 u32 val = clk_readl(c->reg);
1487 int source;
1488
1489 source = val & 0xf;
1490 return source;
1491}
1492
1493static int tegra20_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index)
1494{
1495 struct clk_tegra *c = to_clk_tegra(hw);
1496 u32 val;
1497
1498 val = clk_readl(c->reg);
1499 val &= ~0xf;
1500 val |= index;
1501
1502 clk_writel(val, c->reg);
1503
1504 return 0;
1505}
1506
1507struct clk_ops tegra_audio_sync_clk_ops = {
1508 .is_enabled = tegra20_audio_sync_clk_is_enabled,
1509 .enable = tegra20_audio_sync_clk_enable,
1510 .disable = tegra20_audio_sync_clk_disable,
1511 .set_parent = tegra20_audio_sync_clk_set_parent,
1512 .get_parent = tegra20_audio_sync_clk_get_parent,
1513};
1514
1515/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
1516
1517static int tegra20_cdev_clk_is_enabled(struct clk_hw *hw)
1518{
1519 struct clk_tegra *c = to_clk_tegra(hw);
1520 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
1521 * currently done in the pinmux code. */
1522 c->state = ON;
1523
1524 BUG_ON(!c->u.periph.clk_num);
1525
1526 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1527 PERIPH_CLK_TO_ENB_BIT(c)))
1528 c->state = OFF;
1529 return c->state;
1530}
1531
1532static int tegra20_cdev_clk_enable(struct clk_hw *hw)
1533{
1534 struct clk_tegra *c = to_clk_tegra(hw);
1535 BUG_ON(!c->u.periph.clk_num);
1536
1537 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1538 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
1539 return 0;
1540}
1541
1542static void tegra20_cdev_clk_disable(struct clk_hw *hw)
1543{
1544 struct clk_tegra *c = to_clk_tegra(hw);
1545 BUG_ON(!c->u.periph.clk_num);
1546
1547 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1548 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1549}
1550
1551static unsigned long tegra20_cdev_recalc_rate(struct clk_hw *hw,
1552 unsigned long prate)
1553{
1554 return to_clk_tegra(hw)->fixed_rate;
1555}
1556
1557struct clk_ops tegra_cdev_clk_ops = {
1558 .is_enabled = tegra20_cdev_clk_is_enabled,
1559 .enable = tegra20_cdev_clk_enable,
1560 .disable = tegra20_cdev_clk_disable,
1561 .recalc_rate = tegra20_cdev_recalc_rate,
1562};
1563
1564/* Tegra20 CPU clock and reset control functions */
1565static void tegra20_wait_cpu_in_reset(u32 cpu)
1566{
1567 unsigned int reg;
1568
1569 do {
1570 reg = readl(reg_clk_base +
1571 TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
1572 cpu_relax();
1573 } while (!(reg & (1 << cpu))); /* check CPU been reset or not */
1574
1575 return;
1576}
1577
1578static void tegra20_put_cpu_in_reset(u32 cpu)
1579{
1580 writel(CPU_RESET(cpu),
1581 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
1582 dmb();
1583}
1584
1585static void tegra20_cpu_out_of_reset(u32 cpu)
1586{
1587 writel(CPU_RESET(cpu),
1588 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
1589 wmb();
1590}
1591
1592static void tegra20_enable_cpu_clock(u32 cpu)
1593{
1594 unsigned int reg;
1595
1596 reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1597 writel(reg & ~CPU_CLOCK(cpu),
1598 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1599 barrier();
1600 reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1601}
1602
1603static void tegra20_disable_cpu_clock(u32 cpu)
1604{
1605 unsigned int reg;
1606
1607 reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1608 writel(reg | CPU_CLOCK(cpu),
1609 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1610}
1611
1612static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
1613 .wait_for_reset = tegra20_wait_cpu_in_reset,
1614 .put_in_reset = tegra20_put_cpu_in_reset,
1615 .out_of_reset = tegra20_cpu_out_of_reset,
1616 .enable_clock = tegra20_enable_cpu_clock,
1617 .disable_clock = tegra20_disable_cpu_clock,
1618};
1619
1620void __init tegra20_cpu_car_ops_init(void)
1621{
1622 tegra_cpu_car_ops = &tegra20_cpu_car_ops;
1623}
diff --git a/arch/arm/mach-tegra/tegra20_clocks.h b/arch/arm/mach-tegra/tegra20_clocks.h
deleted file mode 100644
index 8bfd31bcc490..000000000000
--- a/arch/arm/mach-tegra/tegra20_clocks.h
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __MACH_TEGRA20_CLOCK_H
18#define __MACH_TEGRA20_CLOCK_H
19
20extern struct clk_ops tegra_clk_32k_ops;
21extern struct clk_ops tegra_pll_ops;
22extern struct clk_ops tegra_clk_m_ops;
23extern struct clk_ops tegra_pll_div_ops;
24extern struct clk_ops tegra_pllx_ops;
25extern struct clk_ops tegra_plle_ops;
26extern struct clk_ops tegra_clk_double_ops;
27extern struct clk_ops tegra_cdev_clk_ops;
28extern struct clk_ops tegra_audio_sync_clk_ops;
29extern struct clk_ops tegra_super_ops;
30extern struct clk_ops tegra_cpu_ops;
31extern struct clk_ops tegra_twd_ops;
32extern struct clk_ops tegra_cop_ops;
33extern struct clk_ops tegra_bus_ops;
34extern struct clk_ops tegra_blink_clk_ops;
35extern struct clk_ops tegra_emc_clk_ops;
36extern struct clk_ops tegra_periph_clk_ops;
37extern struct clk_ops tegra_clk_shared_bus_ops;
38
39void tegra2_periph_clk_reset(struct clk_hw *hw, bool assert);
40void tegra2_cop_clk_reset(struct clk_hw *hw, bool assert);
41
42#endif
diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c b/arch/arm/mach-tegra/tegra20_clocks_data.c
deleted file mode 100644
index a23a0734e352..000000000000
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ /dev/null
@@ -1,1143 +0,0 @@
1/*
2 * arch/arm/mach-tegra/tegra2_clocks.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
6 *
7 * Author:
8 * Colin Cross <ccross@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <linux/clk-private.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/list.h>
25#include <linux/spinlock.h>
26#include <linux/delay.h>
27#include <linux/io.h>
28#include <linux/clk.h>
29
30#include "clock.h"
31#include "fuse.h"
32#include "tegra2_emc.h"
33#include "tegra20_clocks.h"
34#include "tegra_cpu_car.h"
35
36/* Clock definitions */
37
38#define DEFINE_CLK_TEGRA(_name, _rate, _ops, _flags, \
39 _parent_names, _parents, _parent) \
40 static struct clk tegra_##_name = { \
41 .hw = &tegra_##_name##_hw.hw, \
42 .name = #_name, \
43 .rate = _rate, \
44 .ops = _ops, \
45 .flags = _flags, \
46 .parent_names = _parent_names, \
47 .parents = _parents, \
48 .num_parents = ARRAY_SIZE(_parent_names), \
49 .parent = _parent, \
50 };
51
52static struct clk tegra_clk_32k;
53static struct clk_tegra tegra_clk_32k_hw = {
54 .hw = {
55 .clk = &tegra_clk_32k,
56 },
57 .fixed_rate = 32768,
58};
59
60static struct clk tegra_clk_32k = {
61 .name = "clk_32k",
62 .rate = 32768,
63 .ops = &tegra_clk_32k_ops,
64 .hw = &tegra_clk_32k_hw.hw,
65 .flags = CLK_IS_ROOT,
66};
67
68static struct clk tegra_clk_m;
69static struct clk_tegra tegra_clk_m_hw = {
70 .hw = {
71 .clk = &tegra_clk_m,
72 },
73 .flags = ENABLE_ON_INIT,
74 .reg = 0x1fc,
75 .reg_shift = 28,
76 .max_rate = 26000000,
77 .fixed_rate = 0,
78};
79
80static struct clk tegra_clk_m = {
81 .name = "clk_m",
82 .ops = &tegra_clk_m_ops,
83 .hw = &tegra_clk_m_hw.hw,
84 .flags = CLK_IS_ROOT,
85};
86
87#define DEFINE_PLL(_name, _flags, _reg, _max_rate, _input_min, \
88 _input_max, _cf_min, _cf_max, _vco_min, \
89 _vco_max, _freq_table, _lock_delay, _ops, \
90 _fixed_rate, _parent) \
91 static const char *tegra_##_name##_parent_names[] = { \
92 #_parent, \
93 }; \
94 static struct clk *tegra_##_name##_parents[] = { \
95 &tegra_##_parent, \
96 }; \
97 static struct clk tegra_##_name; \
98 static struct clk_tegra tegra_##_name##_hw = { \
99 .hw = { \
100 .clk = &tegra_##_name, \
101 }, \
102 .flags = _flags, \
103 .reg = _reg, \
104 .max_rate = _max_rate, \
105 .u.pll = { \
106 .input_min = _input_min, \
107 .input_max = _input_max, \
108 .cf_min = _cf_min, \
109 .cf_max = _cf_max, \
110 .vco_min = _vco_min, \
111 .vco_max = _vco_max, \
112 .freq_table = _freq_table, \
113 .lock_delay = _lock_delay, \
114 .fixed_rate = _fixed_rate, \
115 }, \
116 }; \
117 static struct clk tegra_##_name = { \
118 .name = #_name, \
119 .ops = &_ops, \
120 .hw = &tegra_##_name##_hw.hw, \
121 .parent = &tegra_##_parent, \
122 .parent_names = tegra_##_name##_parent_names, \
123 .parents = tegra_##_name##_parents, \
124 .num_parents = 1, \
125 };
126
127#define DEFINE_PLL_OUT(_name, _flags, _reg, _reg_shift, \
128 _max_rate, _ops, _parent, _clk_flags) \
129 static const char *tegra_##_name##_parent_names[] = { \
130 #_parent, \
131 }; \
132 static struct clk *tegra_##_name##_parents[] = { \
133 &tegra_##_parent, \
134 }; \
135 static struct clk tegra_##_name; \
136 static struct clk_tegra tegra_##_name##_hw = { \
137 .hw = { \
138 .clk = &tegra_##_name, \
139 }, \
140 .flags = _flags, \
141 .reg = _reg, \
142 .max_rate = _max_rate, \
143 .reg_shift = _reg_shift, \
144 }; \
145 static struct clk tegra_##_name = { \
146 .name = #_name, \
147 .ops = &tegra_pll_div_ops, \
148 .hw = &tegra_##_name##_hw.hw, \
149 .parent = &tegra_##_parent, \
150 .parent_names = tegra_##_name##_parent_names, \
151 .parents = tegra_##_name##_parents, \
152 .num_parents = 1, \
153 .flags = _clk_flags, \
154 };
155
156
157static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
158 {32768, 12000000, 366, 1, 1, 0},
159 {32768, 13000000, 397, 1, 1, 0},
160 {32768, 19200000, 586, 1, 1, 0},
161 {32768, 26000000, 793, 1, 1, 0},
162 {0, 0, 0, 0, 0, 0},
163};
164
165DEFINE_PLL(pll_s, PLL_ALT_MISC_REG, 0xf0, 26000000, 32768, 32768, 0,
166 0, 12000000, 26000000, tegra_pll_s_freq_table, 300,
167 tegra_pll_ops, 0, clk_32k);
168
169static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
170 { 12000000, 600000000, 600, 12, 1, 8 },
171 { 13000000, 600000000, 600, 13, 1, 8 },
172 { 19200000, 600000000, 500, 16, 1, 6 },
173 { 26000000, 600000000, 600, 26, 1, 8 },
174 { 0, 0, 0, 0, 0, 0 },
175};
176
177DEFINE_PLL(pll_c, PLL_HAS_CPCON, 0x80, 600000000, 2000000, 31000000, 1000000,
178 6000000, 20000000, 1400000000, tegra_pll_c_freq_table, 300,
179 tegra_pll_ops, 0, clk_m);
180
181DEFINE_PLL_OUT(pll_c_out1, DIV_U71, 0x84, 0, 600000000,
182 tegra_pll_div_ops, pll_c, 0);
183
184static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
185 { 12000000, 666000000, 666, 12, 1, 8},
186 { 13000000, 666000000, 666, 13, 1, 8},
187 { 19200000, 666000000, 555, 16, 1, 8},
188 { 26000000, 666000000, 666, 26, 1, 8},
189 { 12000000, 600000000, 600, 12, 1, 8},
190 { 13000000, 600000000, 600, 13, 1, 8},
191 { 19200000, 600000000, 375, 12, 1, 6},
192 { 26000000, 600000000, 600, 26, 1, 8},
193 { 0, 0, 0, 0, 0, 0 },
194};
195
196DEFINE_PLL(pll_m, PLL_HAS_CPCON, 0x90, 800000000, 2000000, 31000000, 1000000,
197 6000000, 20000000, 1200000000, tegra_pll_m_freq_table, 300,
198 tegra_pll_ops, 0, clk_m);
199
200DEFINE_PLL_OUT(pll_m_out1, DIV_U71, 0x94, 0, 600000000,
201 tegra_pll_div_ops, pll_m, 0);
202
203static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
204 { 12000000, 216000000, 432, 12, 2, 8},
205 { 13000000, 216000000, 432, 13, 2, 8},
206 { 19200000, 216000000, 90, 4, 2, 1},
207 { 26000000, 216000000, 432, 26, 2, 8},
208 { 12000000, 432000000, 432, 12, 1, 8},
209 { 13000000, 432000000, 432, 13, 1, 8},
210 { 19200000, 432000000, 90, 4, 1, 1},
211 { 26000000, 432000000, 432, 26, 1, 8},
212 { 0, 0, 0, 0, 0, 0 },
213};
214
215
216DEFINE_PLL(pll_p, ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, 0xa0, 432000000,
217 2000000, 31000000, 1000000, 6000000, 20000000, 1400000000,
218 tegra_pll_p_freq_table, 300, tegra_pll_ops, 216000000, clk_m);
219
220DEFINE_PLL_OUT(pll_p_out1, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4, 0,
221 432000000, tegra_pll_div_ops, pll_p, 0);
222DEFINE_PLL_OUT(pll_p_out2, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4, 16,
223 432000000, tegra_pll_div_ops, pll_p, 0);
224DEFINE_PLL_OUT(pll_p_out3, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8, 0,
225 432000000, tegra_pll_div_ops, pll_p, 0);
226DEFINE_PLL_OUT(pll_p_out4, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8, 16,
227 432000000, tegra_pll_div_ops, pll_p, 0);
228
229static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
230 { 28800000, 56448000, 49, 25, 1, 1},
231 { 28800000, 73728000, 64, 25, 1, 1},
232 { 28800000, 24000000, 5, 6, 1, 1},
233 { 0, 0, 0, 0, 0, 0 },
234};
235
236DEFINE_PLL(pll_a, PLL_HAS_CPCON, 0xb0, 73728000, 2000000, 31000000, 1000000,
237 6000000, 20000000, 1400000000, tegra_pll_a_freq_table, 300,
238 tegra_pll_ops, 0, pll_p_out1);
239
240DEFINE_PLL_OUT(pll_a_out0, DIV_U71, 0xb4, 0, 73728000,
241 tegra_pll_div_ops, pll_a, 0);
242
243static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
244 { 12000000, 216000000, 216, 12, 1, 4},
245 { 13000000, 216000000, 216, 13, 1, 4},
246 { 19200000, 216000000, 135, 12, 1, 3},
247 { 26000000, 216000000, 216, 26, 1, 4},
248
249 { 12000000, 297000000, 99, 4, 1, 4 },
250 { 12000000, 339000000, 113, 4, 1, 4 },
251
252 { 12000000, 594000000, 594, 12, 1, 8},
253 { 13000000, 594000000, 594, 13, 1, 8},
254 { 19200000, 594000000, 495, 16, 1, 8},
255 { 26000000, 594000000, 594, 26, 1, 8},
256
257 { 12000000, 616000000, 616, 12, 1, 8},
258
259 { 12000000, 1000000000, 1000, 12, 1, 12},
260 { 13000000, 1000000000, 1000, 13, 1, 12},
261 { 19200000, 1000000000, 625, 12, 1, 8},
262 { 26000000, 1000000000, 1000, 26, 1, 12},
263
264 { 0, 0, 0, 0, 0, 0 },
265};
266
267DEFINE_PLL(pll_d, PLL_HAS_CPCON | PLLD, 0xd0, 1000000000, 2000000, 40000000,
268 1000000, 6000000, 40000000, 1000000000, tegra_pll_d_freq_table,
269 1000, tegra_pll_ops, 0, clk_m);
270
271DEFINE_PLL_OUT(pll_d_out0, DIV_2 | PLLD, 0, 0, 500000000,
272 tegra_pll_div_ops, pll_d, CLK_SET_RATE_PARENT);
273
274static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
275 { 12000000, 480000000, 960, 12, 2, 0},
276 { 13000000, 480000000, 960, 13, 2, 0},
277 { 19200000, 480000000, 200, 4, 2, 0},
278 { 26000000, 480000000, 960, 26, 2, 0},
279 { 0, 0, 0, 0, 0, 0 },
280};
281
282DEFINE_PLL(pll_u, PLLU, 0xc0, 480000000, 2000000, 40000000, 1000000, 6000000,
283 48000000, 960000000, tegra_pll_u_freq_table, 1000,
284 tegra_pll_ops, 0, clk_m);
285
286static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
287 /* 1 GHz */
288 { 12000000, 1000000000, 1000, 12, 1, 12},
289 { 13000000, 1000000000, 1000, 13, 1, 12},
290 { 19200000, 1000000000, 625, 12, 1, 8},
291 { 26000000, 1000000000, 1000, 26, 1, 12},
292
293 /* 912 MHz */
294 { 12000000, 912000000, 912, 12, 1, 12},
295 { 13000000, 912000000, 912, 13, 1, 12},
296 { 19200000, 912000000, 760, 16, 1, 8},
297 { 26000000, 912000000, 912, 26, 1, 12},
298
299 /* 816 MHz */
300 { 12000000, 816000000, 816, 12, 1, 12},
301 { 13000000, 816000000, 816, 13, 1, 12},
302 { 19200000, 816000000, 680, 16, 1, 8},
303 { 26000000, 816000000, 816, 26, 1, 12},
304
305 /* 760 MHz */
306 { 12000000, 760000000, 760, 12, 1, 12},
307 { 13000000, 760000000, 760, 13, 1, 12},
308 { 19200000, 760000000, 950, 24, 1, 8},
309 { 26000000, 760000000, 760, 26, 1, 12},
310
311 /* 750 MHz */
312 { 12000000, 750000000, 750, 12, 1, 12},
313 { 13000000, 750000000, 750, 13, 1, 12},
314 { 19200000, 750000000, 625, 16, 1, 8},
315 { 26000000, 750000000, 750, 26, 1, 12},
316
317 /* 608 MHz */
318 { 12000000, 608000000, 608, 12, 1, 12},
319 { 13000000, 608000000, 608, 13, 1, 12},
320 { 19200000, 608000000, 380, 12, 1, 8},
321 { 26000000, 608000000, 608, 26, 1, 12},
322
323 /* 456 MHz */
324 { 12000000, 456000000, 456, 12, 1, 12},
325 { 13000000, 456000000, 456, 13, 1, 12},
326 { 19200000, 456000000, 380, 16, 1, 8},
327 { 26000000, 456000000, 456, 26, 1, 12},
328
329 /* 312 MHz */
330 { 12000000, 312000000, 312, 12, 1, 12},
331 { 13000000, 312000000, 312, 13, 1, 12},
332 { 19200000, 312000000, 260, 16, 1, 8},
333 { 26000000, 312000000, 312, 26, 1, 12},
334
335 { 0, 0, 0, 0, 0, 0 },
336};
337
338DEFINE_PLL(pll_x, PLL_HAS_CPCON | PLL_ALT_MISC_REG, 0xe0, 1000000000, 2000000,
339 31000000, 1000000, 6000000, 20000000, 1200000000,
340 tegra_pll_x_freq_table, 300, tegra_pllx_ops, 0, clk_m);
341
342static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
343 { 12000000, 100000000, 200, 24, 1, 0 },
344 { 0, 0, 0, 0, 0, 0 },
345};
346
347DEFINE_PLL(pll_e, PLL_ALT_MISC_REG, 0xe8, 100000000, 12000000, 12000000, 0, 0,
348 0, 0, tegra_pll_e_freq_table, 0, tegra_plle_ops, 0, clk_m);
349
350static const char *tegra_common_parent_names[] = {
351 "clk_m",
352};
353
354static struct clk *tegra_common_parents[] = {
355 &tegra_clk_m,
356};
357
358static struct clk tegra_clk_d;
359static struct clk_tegra tegra_clk_d_hw = {
360 .hw = {
361 .clk = &tegra_clk_d,
362 },
363 .flags = PERIPH_NO_RESET,
364 .reg = 0x34,
365 .reg_shift = 12,
366 .max_rate = 52000000,
367 .u.periph = {
368 .clk_num = 90,
369 },
370};
371
372static struct clk tegra_clk_d = {
373 .name = "clk_d",
374 .hw = &tegra_clk_d_hw.hw,
375 .ops = &tegra_clk_double_ops,
376 .parent = &tegra_clk_m,
377 .parent_names = tegra_common_parent_names,
378 .parents = tegra_common_parents,
379 .num_parents = ARRAY_SIZE(tegra_common_parent_names),
380};
381
382static struct clk tegra_cdev1;
383static struct clk_tegra tegra_cdev1_hw = {
384 .hw = {
385 .clk = &tegra_cdev1,
386 },
387 .fixed_rate = 26000000,
388 .u.periph = {
389 .clk_num = 94,
390 },
391};
392static struct clk tegra_cdev1 = {
393 .name = "cdev1",
394 .hw = &tegra_cdev1_hw.hw,
395 .ops = &tegra_cdev_clk_ops,
396 .flags = CLK_IS_ROOT,
397};
398
399/* dap_mclk2, belongs to the cdev2 pingroup. */
400static struct clk tegra_cdev2;
401static struct clk_tegra tegra_cdev2_hw = {
402 .hw = {
403 .clk = &tegra_cdev2,
404 },
405 .fixed_rate = 26000000,
406 .u.periph = {
407 .clk_num = 93,
408 },
409};
410static struct clk tegra_cdev2 = {
411 .name = "cdev2",
412 .hw = &tegra_cdev2_hw.hw,
413 .ops = &tegra_cdev_clk_ops,
414 .flags = CLK_IS_ROOT,
415};
416
417/* initialized before peripheral clocks */
418static struct clk_mux_sel mux_audio_sync_clk[8+1];
419static const struct audio_sources {
420 const char *name;
421 int value;
422} mux_audio_sync_clk_sources[] = {
423 { .name = "spdif_in", .value = 0 },
424 { .name = "i2s1", .value = 1 },
425 { .name = "i2s2", .value = 2 },
426 { .name = "pll_a_out0", .value = 4 },
427#if 0 /* FIXME: not implemented */
428 { .name = "ac97", .value = 3 },
429 { .name = "ext_audio_clk2", .value = 5 },
430 { .name = "ext_audio_clk1", .value = 6 },
431 { .name = "ext_vimclk", .value = 7 },
432#endif
433 { NULL, 0 }
434};
435
436static const char *audio_parent_names[] = {
437 "spdif_in",
438 "i2s1",
439 "i2s2",
440 "dummy",
441 "pll_a_out0",
442 "dummy",
443 "dummy",
444 "dummy",
445};
446
447static struct clk *audio_parents[] = {
448 NULL,
449 NULL,
450 NULL,
451 NULL,
452 NULL,
453 NULL,
454 NULL,
455 NULL,
456};
457
458static struct clk tegra_audio;
459static struct clk_tegra tegra_audio_hw = {
460 .hw = {
461 .clk = &tegra_audio,
462 },
463 .reg = 0x38,
464 .max_rate = 73728000,
465};
466DEFINE_CLK_TEGRA(audio, 0, &tegra_audio_sync_clk_ops, 0, audio_parent_names,
467 audio_parents, NULL);
468
469static const char *audio_2x_parent_names[] = {
470 "audio",
471};
472
473static struct clk *audio_2x_parents[] = {
474 &tegra_audio,
475};
476
477static struct clk tegra_audio_2x;
478static struct clk_tegra tegra_audio_2x_hw = {
479 .hw = {
480 .clk = &tegra_audio_2x,
481 },
482 .flags = PERIPH_NO_RESET,
483 .max_rate = 48000000,
484 .reg = 0x34,
485 .reg_shift = 8,
486 .u.periph = {
487 .clk_num = 89,
488 },
489};
490DEFINE_CLK_TEGRA(audio_2x, 0, &tegra_clk_double_ops, 0, audio_2x_parent_names,
491 audio_2x_parents, &tegra_audio);
492
493static struct clk_lookup tegra_audio_clk_lookups[] = {
494 { .con_id = "audio", .clk = &tegra_audio },
495 { .con_id = "audio_2x", .clk = &tegra_audio_2x }
496};
497
498/* This is called after peripheral clocks are initialized, as the
499 * audio_sync clock depends on some of the peripheral clocks.
500 */
501
502static void init_audio_sync_clock_mux(void)
503{
504 int i;
505 struct clk_mux_sel *sel = mux_audio_sync_clk;
506 const struct audio_sources *src = mux_audio_sync_clk_sources;
507 struct clk_lookup *lookup;
508
509 for (i = 0; src->name; i++, sel++, src++) {
510 sel->input = tegra_get_clock_by_name(src->name);
511 if (!sel->input)
512 pr_err("%s: could not find clk %s\n", __func__,
513 src->name);
514 audio_parents[src->value] = sel->input;
515 sel->value = src->value;
516 }
517
518 lookup = tegra_audio_clk_lookups;
519 for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
520 struct clk *c = lookup->clk;
521 struct clk_tegra *clk = to_clk_tegra(c->hw);
522 __clk_init(NULL, c);
523 INIT_LIST_HEAD(&clk->shared_bus_list);
524 clk->lookup.con_id = lookup->con_id;
525 clk->lookup.clk = c;
526 clkdev_add(&clk->lookup);
527 tegra_clk_add(c);
528 }
529}
530
531static const char *mux_cclk[] = {
532 "clk_m",
533 "pll_c",
534 "clk_32k",
535 "pll_m",
536 "pll_p",
537 "pll_p_out4",
538 "pll_p_out3",
539 "clk_d",
540 "pll_x",
541};
542
543
544static struct clk *mux_cclk_p[] = {
545 &tegra_clk_m,
546 &tegra_pll_c,
547 &tegra_clk_32k,
548 &tegra_pll_m,
549 &tegra_pll_p,
550 &tegra_pll_p_out4,
551 &tegra_pll_p_out3,
552 &tegra_clk_d,
553 &tegra_pll_x,
554};
555
556static const char *mux_sclk[] = {
557 "clk_m",
558 "pll_c_out1",
559 "pll_p_out4",
560 "pllp_p_out3",
561 "pll_p_out2",
562 "clk_d",
563 "clk_32k",
564 "pll_m_out1",
565};
566
567static struct clk *mux_sclk_p[] = {
568 &tegra_clk_m,
569 &tegra_pll_c_out1,
570 &tegra_pll_p_out4,
571 &tegra_pll_p_out3,
572 &tegra_pll_p_out2,
573 &tegra_clk_d,
574 &tegra_clk_32k,
575 &tegra_pll_m_out1,
576};
577
578static struct clk tegra_cclk;
579static struct clk_tegra tegra_cclk_hw = {
580 .hw = {
581 .clk = &tegra_cclk,
582 },
583 .reg = 0x20,
584 .max_rate = 1000000000,
585};
586DEFINE_CLK_TEGRA(cclk, 0, &tegra_super_ops, 0, mux_cclk,
587 mux_cclk_p, NULL);
588
589static const char *mux_twd[] = {
590 "cclk",
591};
592
593static struct clk *mux_twd_p[] = {
594 &tegra_cclk,
595};
596
597static struct clk tegra_clk_twd;
598static struct clk_tegra tegra_clk_twd_hw = {
599 .hw = {
600 .clk = &tegra_clk_twd,
601 },
602 .max_rate = 1000000000,
603 .mul = 1,
604 .div = 4,
605};
606
607static struct clk tegra_clk_twd = {
608 .name = "twd",
609 .ops = &tegra_twd_ops,
610 .hw = &tegra_clk_twd_hw.hw,
611 .parent = &tegra_cclk,
612 .parent_names = mux_twd,
613 .parents = mux_twd_p,
614 .num_parents = ARRAY_SIZE(mux_twd),
615};
616
617static struct clk tegra_sclk;
618static struct clk_tegra tegra_sclk_hw = {
619 .hw = {
620 .clk = &tegra_sclk,
621 },
622 .reg = 0x28,
623 .max_rate = 240000000,
624 .min_rate = 120000000,
625};
626DEFINE_CLK_TEGRA(sclk, 0, &tegra_super_ops, 0, mux_sclk,
627 mux_sclk_p, NULL);
628
629static const char *tegra_cop_parent_names[] = {
630 "tegra_sclk",
631};
632
633static struct clk *tegra_cop_parents[] = {
634 &tegra_sclk,
635};
636
637static struct clk tegra_cop;
638static struct clk_tegra tegra_cop_hw = {
639 .hw = {
640 .clk = &tegra_cop,
641 },
642 .max_rate = 240000000,
643 .reset = &tegra2_cop_clk_reset,
644};
645DEFINE_CLK_TEGRA(cop, 0, &tegra_cop_ops, CLK_SET_RATE_PARENT,
646 tegra_cop_parent_names, tegra_cop_parents, &tegra_sclk);
647
648static const char *tegra_hclk_parent_names[] = {
649 "tegra_sclk",
650};
651
652static struct clk *tegra_hclk_parents[] = {
653 &tegra_sclk,
654};
655
656static struct clk tegra_hclk;
657static struct clk_tegra tegra_hclk_hw = {
658 .hw = {
659 .clk = &tegra_hclk,
660 },
661 .flags = DIV_BUS,
662 .reg = 0x30,
663 .reg_shift = 4,
664 .max_rate = 240000000,
665};
666DEFINE_CLK_TEGRA(hclk, 0, &tegra_bus_ops, 0, tegra_hclk_parent_names,
667 tegra_hclk_parents, &tegra_sclk);
668
669static const char *tegra_pclk_parent_names[] = {
670 "tegra_hclk",
671};
672
673static struct clk *tegra_pclk_parents[] = {
674 &tegra_hclk,
675};
676
677static struct clk tegra_pclk;
678static struct clk_tegra tegra_pclk_hw = {
679 .hw = {
680 .clk = &tegra_pclk,
681 },
682 .flags = DIV_BUS,
683 .reg = 0x30,
684 .reg_shift = 0,
685 .max_rate = 120000000,
686};
687DEFINE_CLK_TEGRA(pclk, 0, &tegra_bus_ops, 0, tegra_pclk_parent_names,
688 tegra_pclk_parents, &tegra_hclk);
689
690static const char *tegra_blink_parent_names[] = {
691 "clk_32k",
692};
693
694static struct clk *tegra_blink_parents[] = {
695 &tegra_clk_32k,
696};
697
698static struct clk tegra_blink;
699static struct clk_tegra tegra_blink_hw = {
700 .hw = {
701 .clk = &tegra_blink,
702 },
703 .reg = 0x40,
704 .max_rate = 32768,
705};
706DEFINE_CLK_TEGRA(blink, 0, &tegra_blink_clk_ops, 0, tegra_blink_parent_names,
707 tegra_blink_parents, &tegra_clk_32k);
708
709static const char *mux_pllm_pllc_pllp_plla[] = {
710 "pll_m",
711 "pll_c",
712 "pll_p",
713 "pll_a_out0",
714};
715
716static struct clk *mux_pllm_pllc_pllp_plla_p[] = {
717 &tegra_pll_m,
718 &tegra_pll_c,
719 &tegra_pll_p,
720 &tegra_pll_a_out0,
721};
722
723static const char *mux_pllm_pllc_pllp_clkm[] = {
724 "pll_m",
725 "pll_c",
726 "pll_p",
727 "clk_m",
728};
729
730static struct clk *mux_pllm_pllc_pllp_clkm_p[] = {
731 &tegra_pll_m,
732 &tegra_pll_c,
733 &tegra_pll_p,
734 &tegra_clk_m,
735};
736
737static const char *mux_pllp_pllc_pllm_clkm[] = {
738 "pll_p",
739 "pll_c",
740 "pll_m",
741 "clk_m",
742};
743
744static struct clk *mux_pllp_pllc_pllm_clkm_p[] = {
745 &tegra_pll_p,
746 &tegra_pll_c,
747 &tegra_pll_m,
748 &tegra_clk_m,
749};
750
751static const char *mux_pllaout0_audio2x_pllp_clkm[] = {
752 "pll_a_out0",
753 "audio_2x",
754 "pll_p",
755 "clk_m",
756};
757
758static struct clk *mux_pllaout0_audio2x_pllp_clkm_p[] = {
759 &tegra_pll_a_out0,
760 &tegra_audio_2x,
761 &tegra_pll_p,
762 &tegra_clk_m,
763};
764
765static const char *mux_pllp_plld_pllc_clkm[] = {
766 "pllp",
767 "pll_d_out0",
768 "pll_c",
769 "clk_m",
770};
771
772static struct clk *mux_pllp_plld_pllc_clkm_p[] = {
773 &tegra_pll_p,
774 &tegra_pll_d_out0,
775 &tegra_pll_c,
776 &tegra_clk_m,
777};
778
779static const char *mux_pllp_pllc_audio_clkm_clk32[] = {
780 "pll_p",
781 "pll_c",
782 "audio",
783 "clk_m",
784 "clk_32k",
785};
786
787static struct clk *mux_pllp_pllc_audio_clkm_clk32_p[] = {
788 &tegra_pll_p,
789 &tegra_pll_c,
790 &tegra_audio,
791 &tegra_clk_m,
792 &tegra_clk_32k,
793};
794
795static const char *mux_pllp_pllc_pllm[] = {
796 "pll_p",
797 "pll_c",
798 "pll_m"
799};
800
801static struct clk *mux_pllp_pllc_pllm_p[] = {
802 &tegra_pll_p,
803 &tegra_pll_c,
804 &tegra_pll_m,
805};
806
807static const char *mux_clk_m[] = {
808 "clk_m",
809};
810
811static struct clk *mux_clk_m_p[] = {
812 &tegra_clk_m,
813};
814
815static const char *mux_pllp_out3[] = {
816 "pll_p_out3",
817};
818
819static struct clk *mux_pllp_out3_p[] = {
820 &tegra_pll_p_out3,
821};
822
823static const char *mux_plld[] = {
824 "pll_d",
825};
826
827static struct clk *mux_plld_p[] = {
828 &tegra_pll_d,
829};
830
831static const char *mux_clk_32k[] = {
832 "clk_32k",
833};
834
835static struct clk *mux_clk_32k_p[] = {
836 &tegra_clk_32k,
837};
838
839static const char *mux_pclk[] = {
840 "pclk",
841};
842
843static struct clk *mux_pclk_p[] = {
844 &tegra_pclk,
845};
846
847static struct clk tegra_emc;
848static struct clk_tegra tegra_emc_hw = {
849 .hw = {
850 .clk = &tegra_emc,
851 },
852 .reg = 0x19c,
853 .max_rate = 800000000,
854 .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
855 .reset = &tegra2_periph_clk_reset,
856 .u.periph = {
857 .clk_num = 57,
858 },
859};
860DEFINE_CLK_TEGRA(emc, 0, &tegra_emc_clk_ops, 0, mux_pllm_pllc_pllp_clkm,
861 mux_pllm_pllc_pllp_clkm_p, NULL);
862
863#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, \
864 _max, _inputs, _flags) \
865 static struct clk tegra_##_name; \
866 static struct clk_tegra tegra_##_name##_hw = { \
867 .hw = { \
868 .clk = &tegra_##_name, \
869 }, \
870 .lookup = { \
871 .dev_id = _dev, \
872 .con_id = _con, \
873 }, \
874 .reg = _reg, \
875 .flags = _flags, \
876 .max_rate = _max, \
877 .u.periph = { \
878 .clk_num = _clk_num, \
879 }, \
880 .reset = tegra2_periph_clk_reset, \
881 }; \
882 static struct clk tegra_##_name = { \
883 .name = #_name, \
884 .ops = &tegra_periph_clk_ops, \
885 .hw = &tegra_##_name##_hw.hw, \
886 .parent_names = _inputs, \
887 .parents = _inputs##_p, \
888 .num_parents = ARRAY_SIZE(_inputs), \
889 };
890
891PERIPH_CLK(apbdma, "tegra-apbdma", NULL, 34, 0, 108000000, mux_pclk, 0);
892PERIPH_CLK(rtc, "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET);
893PERIPH_CLK(timer, "timer", NULL, 5, 0, 26000000, mux_clk_m, 0);
894PERIPH_CLK(i2s1, "tegra20-i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71);
895PERIPH_CLK(i2s2, "tegra20-i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71);
896PERIPH_CLK(spdif_out, "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71);
897PERIPH_CLK(spdif_in, "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71);
898PERIPH_CLK(pwm, "tegra-pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71 | MUX_PWM);
899PERIPH_CLK(spi, "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
900PERIPH_CLK(xio, "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
901PERIPH_CLK(twc, "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
902PERIPH_CLK(sbc1, "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
903PERIPH_CLK(sbc2, "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
904PERIPH_CLK(sbc3, "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
905PERIPH_CLK(sbc4, "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
906PERIPH_CLK(ide, "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* requires min voltage */
907PERIPH_CLK(ndflash, "tegra_nand", NULL, 13, 0x160, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
908PERIPH_CLK(vfir, "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
909PERIPH_CLK(sdmmc1, "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
910PERIPH_CLK(sdmmc2, "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
911PERIPH_CLK(sdmmc3, "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
912PERIPH_CLK(sdmmc4, "sdhci-tegra.3", NULL, 15, 0x164, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
913PERIPH_CLK(vcp, "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0);
914PERIPH_CLK(bsea, "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0);
915PERIPH_CLK(bsev, "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0);
916PERIPH_CLK(vde, "tegra-avp", "vde", 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage and process_id */
917PERIPH_CLK(csite, "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* max rate ??? */
918/* FIXME: what is la? */
919PERIPH_CLK(la, "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
920PERIPH_CLK(owr, "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
921PERIPH_CLK(nor, "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* requires min voltage */
922PERIPH_CLK(mipi, "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
923PERIPH_CLK(i2c1, "tegra-i2c.0", "div-clk", 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
924PERIPH_CLK(i2c2, "tegra-i2c.1", "div-clk", 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
925PERIPH_CLK(i2c3, "tegra-i2c.2", "div-clk", 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
926PERIPH_CLK(dvc, "tegra-i2c.3", "div-clk", 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
927PERIPH_CLK(uarta, "tegra-uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX);
928PERIPH_CLK(uartb, "tegra-uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX);
929PERIPH_CLK(uartc, "tegra-uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX);
930PERIPH_CLK(uartd, "tegra-uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX);
931PERIPH_CLK(uarte, "tegra-uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX);
932PERIPH_CLK(3d, "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET); /* scales with voltage and process_id */
933PERIPH_CLK(2d, "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */
934PERIPH_CLK(vi, "tegra_camera", "vi", 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */
935PERIPH_CLK(vi_sensor, "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET); /* scales with voltage and process_id */
936PERIPH_CLK(epp, "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */
937PERIPH_CLK(mpe, "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */
938PERIPH_CLK(host1x, "host1x", NULL, 28, 0x180, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */
939PERIPH_CLK(cve, "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */
940PERIPH_CLK(tvo, "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */
941PERIPH_CLK(hdmi, "hdmi", NULL, 51, 0x18c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */
942PERIPH_CLK(tvdac, "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */
943PERIPH_CLK(disp1, "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX); /* scales with voltage and process_id */
944PERIPH_CLK(disp2, "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_plld_pllc_clkm, MUX); /* scales with voltage and process_id */
945PERIPH_CLK(usbd, "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0); /* requires min voltage */
946PERIPH_CLK(usb2, "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0); /* requires min voltage */
947PERIPH_CLK(usb3, "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0); /* requires min voltage */
948PERIPH_CLK(dsi, "dsi", NULL, 48, 0, 500000000, mux_plld, 0); /* scales with voltage */
949PERIPH_CLK(csi, "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0);
950PERIPH_CLK(isp, "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0); /* same frequency as VI */
951PERIPH_CLK(csus, "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET);
952PERIPH_CLK(pex, NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET);
953PERIPH_CLK(afi, NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET);
954PERIPH_CLK(pcie_xclk, NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET);
955
956static struct clk *tegra_list_clks[] = {
957 &tegra_apbdma,
958 &tegra_rtc,
959 &tegra_timer,
960 &tegra_i2s1,
961 &tegra_i2s2,
962 &tegra_spdif_out,
963 &tegra_spdif_in,
964 &tegra_pwm,
965 &tegra_spi,
966 &tegra_xio,
967 &tegra_twc,
968 &tegra_sbc1,
969 &tegra_sbc2,
970 &tegra_sbc3,
971 &tegra_sbc4,
972 &tegra_ide,
973 &tegra_ndflash,
974 &tegra_vfir,
975 &tegra_sdmmc1,
976 &tegra_sdmmc2,
977 &tegra_sdmmc3,
978 &tegra_sdmmc4,
979 &tegra_vcp,
980 &tegra_bsea,
981 &tegra_bsev,
982 &tegra_vde,
983 &tegra_csite,
984 &tegra_la,
985 &tegra_owr,
986 &tegra_nor,
987 &tegra_mipi,
988 &tegra_i2c1,
989 &tegra_i2c2,
990 &tegra_i2c3,
991 &tegra_dvc,
992 &tegra_uarta,
993 &tegra_uartb,
994 &tegra_uartc,
995 &tegra_uartd,
996 &tegra_uarte,
997 &tegra_3d,
998 &tegra_2d,
999 &tegra_vi,
1000 &tegra_vi_sensor,
1001 &tegra_epp,
1002 &tegra_mpe,
1003 &tegra_host1x,
1004 &tegra_cve,
1005 &tegra_tvo,
1006 &tegra_hdmi,
1007 &tegra_tvdac,
1008 &tegra_disp1,
1009 &tegra_disp2,
1010 &tegra_usbd,
1011 &tegra_usb2,
1012 &tegra_usb3,
1013 &tegra_dsi,
1014 &tegra_csi,
1015 &tegra_isp,
1016 &tegra_csus,
1017 &tegra_pex,
1018 &tegra_afi,
1019 &tegra_pcie_xclk,
1020};
1021
1022#define CLK_DUPLICATE(_name, _dev, _con) \
1023 { \
1024 .name = _name, \
1025 .lookup = { \
1026 .dev_id = _dev, \
1027 .con_id = _con, \
1028 }, \
1029 }
1030
1031/* Some clocks may be used by different drivers depending on the board
1032 * configuration. List those here to register them twice in the clock lookup
1033 * table under two names.
1034 */
1035static struct clk_duplicate tegra_clk_duplicates[] = {
1036 CLK_DUPLICATE("uarta", "serial8250.0", NULL),
1037 CLK_DUPLICATE("uartb", "serial8250.1", NULL),
1038 CLK_DUPLICATE("uartc", "serial8250.2", NULL),
1039 CLK_DUPLICATE("uartd", "serial8250.3", NULL),
1040 CLK_DUPLICATE("uarte", "serial8250.4", NULL),
1041 CLK_DUPLICATE("usbd", "utmip-pad", NULL),
1042 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
1043 CLK_DUPLICATE("usbd", "tegra-otg", NULL),
1044 CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"),
1045 CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"),
1046 CLK_DUPLICATE("epp", "tegra_grhost", "epp"),
1047 CLK_DUPLICATE("mpe", "tegra_grhost", "mpe"),
1048 CLK_DUPLICATE("cop", "tegra-avp", "cop"),
1049 CLK_DUPLICATE("vde", "tegra-aes", "vde"),
1050 CLK_DUPLICATE("cclk", NULL, "cpu"),
1051 CLK_DUPLICATE("twd", "smp_twd", NULL),
1052 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.0", "fast-clk"),
1053 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.1", "fast-clk"),
1054 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"),
1055 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"),
1056 CLK_DUPLICATE("pll_p", "tegradc.0", "parent"),
1057 CLK_DUPLICATE("pll_p", "tegradc.1", "parent"),
1058 CLK_DUPLICATE("pll_d_out0", "hdmi", "parent"),
1059};
1060
1061#define CLK(dev, con, ck) \
1062 { \
1063 .dev_id = dev, \
1064 .con_id = con, \
1065 .clk = ck, \
1066 }
1067
1068static struct clk *tegra_ptr_clks[] = {
1069 &tegra_clk_32k,
1070 &tegra_pll_s,
1071 &tegra_clk_m,
1072 &tegra_pll_m,
1073 &tegra_pll_m_out1,
1074 &tegra_pll_c,
1075 &tegra_pll_c_out1,
1076 &tegra_pll_p,
1077 &tegra_pll_p_out1,
1078 &tegra_pll_p_out2,
1079 &tegra_pll_p_out3,
1080 &tegra_pll_p_out4,
1081 &tegra_pll_a,
1082 &tegra_pll_a_out0,
1083 &tegra_pll_d,
1084 &tegra_pll_d_out0,
1085 &tegra_pll_u,
1086 &tegra_pll_x,
1087 &tegra_pll_e,
1088 &tegra_cclk,
1089 &tegra_clk_twd,
1090 &tegra_sclk,
1091 &tegra_hclk,
1092 &tegra_pclk,
1093 &tegra_clk_d,
1094 &tegra_cdev1,
1095 &tegra_cdev2,
1096 &tegra_blink,
1097 &tegra_cop,
1098 &tegra_emc,
1099};
1100
1101static void tegra2_init_one_clock(struct clk *c)
1102{
1103 struct clk_tegra *clk = to_clk_tegra(c->hw);
1104 int ret;
1105
1106 ret = __clk_init(NULL, c);
1107 if (ret)
1108 pr_err("clk init failed %s\n", __clk_get_name(c));
1109
1110 INIT_LIST_HEAD(&clk->shared_bus_list);
1111 if (!clk->lookup.dev_id && !clk->lookup.con_id)
1112 clk->lookup.con_id = c->name;
1113 clk->lookup.clk = c;
1114 clkdev_add(&clk->lookup);
1115 tegra_clk_add(c);
1116}
1117
1118void __init tegra2_init_clocks(void)
1119{
1120 int i;
1121 struct clk *c;
1122
1123 for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
1124 tegra2_init_one_clock(tegra_ptr_clks[i]);
1125
1126 for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
1127 tegra2_init_one_clock(tegra_list_clks[i]);
1128
1129 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
1130 c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
1131 if (!c) {
1132 pr_err("%s: Unknown duplicate clock %s\n", __func__,
1133 tegra_clk_duplicates[i].name);
1134 continue;
1135 }
1136
1137 tegra_clk_duplicates[i].lookup.clk = c;
1138 clkdev_add(&tegra_clk_duplicates[i].lookup);
1139 }
1140
1141 init_audio_sync_clock_mux();
1142 tegra20_cpu_car_ops_init();
1143}
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c
deleted file mode 100644
index d7147779f8ea..000000000000
--- a/arch/arm/mach-tegra/tegra30_clocks.c
+++ /dev/null
@@ -1,2506 +0,0 @@
1/*
2 * arch/arm/mach-tegra/tegra30_clocks.c
3 *
4 * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/list.h>
24#include <linux/spinlock.h>
25#include <linux/delay.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/clk.h>
29#include <linux/cpufreq.h>
30#include <linux/syscore_ops.h>
31
32#include <asm/clkdev.h>
33
34#include <mach/powergate.h>
35
36#include "clock.h"
37#include "fuse.h"
38#include "iomap.h"
39#include "tegra_cpu_car.h"
40
41#define USE_PLL_LOCK_BITS 0
42
43#define RST_DEVICES_L 0x004
44#define RST_DEVICES_H 0x008
45#define RST_DEVICES_U 0x00C
46#define RST_DEVICES_V 0x358
47#define RST_DEVICES_W 0x35C
48#define RST_DEVICES_SET_L 0x300
49#define RST_DEVICES_CLR_L 0x304
50#define RST_DEVICES_SET_V 0x430
51#define RST_DEVICES_CLR_V 0x434
52#define RST_DEVICES_NUM 5
53
54#define CLK_OUT_ENB_L 0x010
55#define CLK_OUT_ENB_H 0x014
56#define CLK_OUT_ENB_U 0x018
57#define CLK_OUT_ENB_V 0x360
58#define CLK_OUT_ENB_W 0x364
59#define CLK_OUT_ENB_SET_L 0x320
60#define CLK_OUT_ENB_CLR_L 0x324
61#define CLK_OUT_ENB_SET_V 0x440
62#define CLK_OUT_ENB_CLR_V 0x444
63#define CLK_OUT_ENB_NUM 5
64
65#define RST_DEVICES_V_SWR_CPULP_RST_DIS (0x1 << 1)
66#define CLK_OUT_ENB_V_CLK_ENB_CPULP_EN (0x1 << 1)
67
68#define PERIPH_CLK_TO_BIT(c) (1 << (c->u.periph.clk_num % 32))
69#define PERIPH_CLK_TO_RST_REG(c) \
70 periph_clk_to_reg((c), RST_DEVICES_L, RST_DEVICES_V, 4)
71#define PERIPH_CLK_TO_RST_SET_REG(c) \
72 periph_clk_to_reg((c), RST_DEVICES_SET_L, RST_DEVICES_SET_V, 8)
73#define PERIPH_CLK_TO_RST_CLR_REG(c) \
74 periph_clk_to_reg((c), RST_DEVICES_CLR_L, RST_DEVICES_CLR_V, 8)
75
76#define PERIPH_CLK_TO_ENB_REG(c) \
77 periph_clk_to_reg((c), CLK_OUT_ENB_L, CLK_OUT_ENB_V, 4)
78#define PERIPH_CLK_TO_ENB_SET_REG(c) \
79 periph_clk_to_reg((c), CLK_OUT_ENB_SET_L, CLK_OUT_ENB_SET_V, 8)
80#define PERIPH_CLK_TO_ENB_CLR_REG(c) \
81 periph_clk_to_reg((c), CLK_OUT_ENB_CLR_L, CLK_OUT_ENB_CLR_V, 8)
82
83#define CLK_MASK_ARM 0x44
84#define MISC_CLK_ENB 0x48
85
86#define OSC_CTRL 0x50
87#define OSC_CTRL_OSC_FREQ_MASK (0xF<<28)
88#define OSC_CTRL_OSC_FREQ_13MHZ (0x0<<28)
89#define OSC_CTRL_OSC_FREQ_19_2MHZ (0x4<<28)
90#define OSC_CTRL_OSC_FREQ_12MHZ (0x8<<28)
91#define OSC_CTRL_OSC_FREQ_26MHZ (0xC<<28)
92#define OSC_CTRL_OSC_FREQ_16_8MHZ (0x1<<28)
93#define OSC_CTRL_OSC_FREQ_38_4MHZ (0x5<<28)
94#define OSC_CTRL_OSC_FREQ_48MHZ (0x9<<28)
95#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
96
97#define OSC_CTRL_PLL_REF_DIV_MASK (3<<26)
98#define OSC_CTRL_PLL_REF_DIV_1 (0<<26)
99#define OSC_CTRL_PLL_REF_DIV_2 (1<<26)
100#define OSC_CTRL_PLL_REF_DIV_4 (2<<26)
101
102#define OSC_FREQ_DET 0x58
103#define OSC_FREQ_DET_TRIG (1<<31)
104
105#define OSC_FREQ_DET_STATUS 0x5C
106#define OSC_FREQ_DET_BUSY (1<<31)
107#define OSC_FREQ_DET_CNT_MASK 0xFFFF
108
109#define PERIPH_CLK_SOURCE_I2S1 0x100
110#define PERIPH_CLK_SOURCE_EMC 0x19c
111#define PERIPH_CLK_SOURCE_OSC 0x1fc
112#define PERIPH_CLK_SOURCE_NUM1 \
113 ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
114
115#define PERIPH_CLK_SOURCE_G3D2 0x3b0
116#define PERIPH_CLK_SOURCE_SE 0x42c
117#define PERIPH_CLK_SOURCE_NUM2 \
118 ((PERIPH_CLK_SOURCE_SE - PERIPH_CLK_SOURCE_G3D2) / 4 + 1)
119
120#define AUDIO_DLY_CLK 0x49c
121#define AUDIO_SYNC_CLK_SPDIF 0x4b4
122#define PERIPH_CLK_SOURCE_NUM3 \
123 ((AUDIO_SYNC_CLK_SPDIF - AUDIO_DLY_CLK) / 4 + 1)
124
125#define PERIPH_CLK_SOURCE_NUM (PERIPH_CLK_SOURCE_NUM1 + \
126 PERIPH_CLK_SOURCE_NUM2 + \
127 PERIPH_CLK_SOURCE_NUM3)
128
129#define CPU_SOFTRST_CTRL 0x380
130
131#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
132#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
133#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
134#define PERIPH_CLK_SOURCE_DIVIDLE_SHIFT 8
135#define PERIPH_CLK_SOURCE_DIVIDLE_VAL 50
136#define PERIPH_CLK_UART_DIV_ENB (1<<24)
137#define PERIPH_CLK_VI_SEL_EX_SHIFT 24
138#define PERIPH_CLK_VI_SEL_EX_MASK (0x3<<PERIPH_CLK_VI_SEL_EX_SHIFT)
139#define PERIPH_CLK_NAND_DIV_EX_ENB (1<<8)
140#define PERIPH_CLK_DTV_POLARITY_INV (1<<25)
141
142#define AUDIO_SYNC_SOURCE_MASK 0x0F
143#define AUDIO_SYNC_DISABLE_BIT 0x10
144#define AUDIO_SYNC_TAP_NIBBLE_SHIFT(c) ((c->reg_shift - 24) * 4)
145
146#define PLL_BASE 0x0
147#define PLL_BASE_BYPASS (1<<31)
148#define PLL_BASE_ENABLE (1<<30)
149#define PLL_BASE_REF_ENABLE (1<<29)
150#define PLL_BASE_OVERRIDE (1<<28)
151#define PLL_BASE_LOCK (1<<27)
152#define PLL_BASE_DIVP_MASK (0x7<<20)
153#define PLL_BASE_DIVP_SHIFT 20
154#define PLL_BASE_DIVN_MASK (0x3FF<<8)
155#define PLL_BASE_DIVN_SHIFT 8
156#define PLL_BASE_DIVM_MASK (0x1F)
157#define PLL_BASE_DIVM_SHIFT 0
158
159#define PLL_OUT_RATIO_MASK (0xFF<<8)
160#define PLL_OUT_RATIO_SHIFT 8
161#define PLL_OUT_OVERRIDE (1<<2)
162#define PLL_OUT_CLKEN (1<<1)
163#define PLL_OUT_RESET_DISABLE (1<<0)
164
165#define PLL_MISC(c) \
166 (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
167#define PLL_MISC_LOCK_ENABLE(c) \
168 (((c)->flags & (PLLU | PLLD)) ? (1<<22) : (1<<18))
169
170#define PLL_MISC_DCCON_SHIFT 20
171#define PLL_MISC_CPCON_SHIFT 8
172#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
173#define PLL_MISC_LFCON_SHIFT 4
174#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
175#define PLL_MISC_VCOCON_SHIFT 0
176#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
177#define PLLD_MISC_CLKENABLE (1<<30)
178
179#define PLLU_BASE_POST_DIV (1<<20)
180
181#define PLLD_BASE_DSIB_MUX_SHIFT 25
182#define PLLD_BASE_DSIB_MUX_MASK (1<<PLLD_BASE_DSIB_MUX_SHIFT)
183#define PLLD_BASE_CSI_CLKENABLE (1<<26)
184#define PLLD_MISC_DSI_CLKENABLE (1<<30)
185#define PLLD_MISC_DIV_RST (1<<23)
186#define PLLD_MISC_DCCON_SHIFT 12
187
188#define PLLDU_LFCON_SET_DIVN 600
189
190/* FIXME: OUT_OF_TABLE_CPCON per pll */
191#define OUT_OF_TABLE_CPCON 0x8
192
193#define SUPER_CLK_MUX 0x00
194#define SUPER_STATE_SHIFT 28
195#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
196#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
197#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
198#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
199#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
200#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
201#define SUPER_LP_DIV2_BYPASS (0x1 << 16)
202#define SUPER_SOURCE_MASK 0xF
203#define SUPER_FIQ_SOURCE_SHIFT 12
204#define SUPER_IRQ_SOURCE_SHIFT 8
205#define SUPER_RUN_SOURCE_SHIFT 4
206#define SUPER_IDLE_SOURCE_SHIFT 0
207
208#define SUPER_CLK_DIVIDER 0x04
209#define SUPER_CLOCK_DIV_U71_SHIFT 16
210#define SUPER_CLOCK_DIV_U71_MASK (0xff << SUPER_CLOCK_DIV_U71_SHIFT)
211/* guarantees safe cpu backup */
212#define SUPER_CLOCK_DIV_U71_MIN 0x2
213
214#define BUS_CLK_DISABLE (1<<3)
215#define BUS_CLK_DIV_MASK 0x3
216
217#define PMC_CTRL 0x0
218 #define PMC_CTRL_BLINK_ENB (1 << 7)
219
220#define PMC_DPD_PADS_ORIDE 0x1c
221 #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
222
223#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
224#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
225#define PMC_BLINK_TIMER_ENB (1 << 15)
226#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
227#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
228
229#define PMC_PLLP_WB0_OVERRIDE 0xf8
230#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE (1 << 12)
231
232#define UTMIP_PLL_CFG2 0x488
233#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xfff) << 6)
234#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
235#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN (1 << 0)
236#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN (1 << 2)
237#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN (1 << 4)
238
239#define UTMIP_PLL_CFG1 0x484
240#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
241#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
242#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN (1 << 14)
243#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN (1 << 12)
244#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN (1 << 16)
245
246#define PLLE_BASE_CML_ENABLE (1<<31)
247#define PLLE_BASE_ENABLE (1<<30)
248#define PLLE_BASE_DIVCML_SHIFT 24
249#define PLLE_BASE_DIVCML_MASK (0xf<<PLLE_BASE_DIVCML_SHIFT)
250#define PLLE_BASE_DIVP_SHIFT 16
251#define PLLE_BASE_DIVP_MASK (0x3f<<PLLE_BASE_DIVP_SHIFT)
252#define PLLE_BASE_DIVN_SHIFT 8
253#define PLLE_BASE_DIVN_MASK (0xFF<<PLLE_BASE_DIVN_SHIFT)
254#define PLLE_BASE_DIVM_SHIFT 0
255#define PLLE_BASE_DIVM_MASK (0xFF<<PLLE_BASE_DIVM_SHIFT)
256#define PLLE_BASE_DIV_MASK \
257 (PLLE_BASE_DIVCML_MASK | PLLE_BASE_DIVP_MASK | \
258 PLLE_BASE_DIVN_MASK | PLLE_BASE_DIVM_MASK)
259#define PLLE_BASE_DIV(m, n, p, cml) \
260 (((cml)<<PLLE_BASE_DIVCML_SHIFT) | ((p)<<PLLE_BASE_DIVP_SHIFT) | \
261 ((n)<<PLLE_BASE_DIVN_SHIFT) | ((m)<<PLLE_BASE_DIVM_SHIFT))
262
263#define PLLE_MISC_SETUP_BASE_SHIFT 16
264#define PLLE_MISC_SETUP_BASE_MASK (0xFFFF<<PLLE_MISC_SETUP_BASE_SHIFT)
265#define PLLE_MISC_READY (1<<15)
266#define PLLE_MISC_LOCK (1<<11)
267#define PLLE_MISC_LOCK_ENABLE (1<<9)
268#define PLLE_MISC_SETUP_EX_SHIFT 2
269#define PLLE_MISC_SETUP_EX_MASK (0x3<<PLLE_MISC_SETUP_EX_SHIFT)
270#define PLLE_MISC_SETUP_MASK \
271 (PLLE_MISC_SETUP_BASE_MASK | PLLE_MISC_SETUP_EX_MASK)
272#define PLLE_MISC_SETUP_VALUE \
273 ((0x7<<PLLE_MISC_SETUP_BASE_SHIFT) | (0x0<<PLLE_MISC_SETUP_EX_SHIFT))
274
275#define PLLE_SS_CTRL 0x68
276#define PLLE_SS_INCINTRV_SHIFT 24
277#define PLLE_SS_INCINTRV_MASK (0x3f<<PLLE_SS_INCINTRV_SHIFT)
278#define PLLE_SS_INC_SHIFT 16
279#define PLLE_SS_INC_MASK (0xff<<PLLE_SS_INC_SHIFT)
280#define PLLE_SS_MAX_SHIFT 0
281#define PLLE_SS_MAX_MASK (0x1ff<<PLLE_SS_MAX_SHIFT)
282#define PLLE_SS_COEFFICIENTS_MASK \
283 (PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK)
284#define PLLE_SS_COEFFICIENTS_12MHZ \
285 ((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \
286 (0x24<<PLLE_SS_MAX_SHIFT))
287#define PLLE_SS_DISABLE ((1<<12) | (1<<11) | (1<<10))
288
289#define PLLE_AUX 0x48c
290#define PLLE_AUX_PLLP_SEL (1<<2)
291#define PLLE_AUX_CML_SATA_ENABLE (1<<1)
292#define PLLE_AUX_CML_PCIE_ENABLE (1<<0)
293
294#define PMC_SATA_PWRGT 0x1ac
295#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE (1<<5)
296#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1<<4)
297
298#define ROUND_DIVIDER_UP 0
299#define ROUND_DIVIDER_DOWN 1
300
301/* FIXME: recommended safety delay after lock is detected */
302#define PLL_POST_LOCK_DELAY 100
303
304/* Tegra CPU clock and reset control regs */
305#define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c
306#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340
307#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344
308#define TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR 0x34c
309#define TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
310
311#define CPU_CLOCK(cpu) (0x1 << (8 + cpu))
312#define CPU_RESET(cpu) (0x1111ul << (cpu))
313
314#define CLK_RESET_CCLK_BURST 0x20
315#define CLK_RESET_CCLK_DIVIDER 0x24
316#define CLK_RESET_PLLX_BASE 0xe0
317#define CLK_RESET_PLLX_MISC 0xe4
318
319#define CLK_RESET_SOURCE_CSITE 0x1d4
320
321#define CLK_RESET_CCLK_BURST_POLICY_SHIFT 28
322#define CLK_RESET_CCLK_RUN_POLICY_SHIFT 4
323#define CLK_RESET_CCLK_IDLE_POLICY_SHIFT 0
324#define CLK_RESET_CCLK_IDLE_POLICY 1
325#define CLK_RESET_CCLK_RUN_POLICY 2
326#define CLK_RESET_CCLK_BURST_POLICY_PLLX 8
327
328#ifdef CONFIG_PM_SLEEP
329static struct cpu_clk_suspend_context {
330 u32 pllx_misc;
331 u32 pllx_base;
332
333 u32 cpu_burst;
334 u32 clk_csite_src;
335 u32 cclk_divider;
336} tegra30_cpu_clk_sctx;
337#endif
338
339/**
340* Structure defining the fields for USB UTMI clocks Parameters.
341*/
342struct utmi_clk_param {
343 /* Oscillator Frequency in KHz */
344 u32 osc_frequency;
345 /* UTMIP PLL Enable Delay Count */
346 u8 enable_delay_count;
347 /* UTMIP PLL Stable count */
348 u8 stable_count;
349 /* UTMIP PLL Active delay count */
350 u8 active_delay_count;
351 /* UTMIP PLL Xtal frequency count */
352 u8 xtal_freq_count;
353};
354
355static const struct utmi_clk_param utmi_parameters[] = {
356 {
357 .osc_frequency = 13000000,
358 .enable_delay_count = 0x02,
359 .stable_count = 0x33,
360 .active_delay_count = 0x05,
361 .xtal_freq_count = 0x7F
362 },
363 {
364 .osc_frequency = 19200000,
365 .enable_delay_count = 0x03,
366 .stable_count = 0x4B,
367 .active_delay_count = 0x06,
368 .xtal_freq_count = 0xBB},
369 {
370 .osc_frequency = 12000000,
371 .enable_delay_count = 0x02,
372 .stable_count = 0x2F,
373 .active_delay_count = 0x04,
374 .xtal_freq_count = 0x76
375 },
376 {
377 .osc_frequency = 26000000,
378 .enable_delay_count = 0x04,
379 .stable_count = 0x66,
380 .active_delay_count = 0x09,
381 .xtal_freq_count = 0xFE
382 },
383 {
384 .osc_frequency = 16800000,
385 .enable_delay_count = 0x03,
386 .stable_count = 0x41,
387 .active_delay_count = 0x0A,
388 .xtal_freq_count = 0xA4
389 },
390};
391
392static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
393static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
394static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
395
396#define MISC_GP_HIDREV 0x804
397
398/*
399 * Some peripheral clocks share an enable bit, so refcount the enable bits
400 * in registers CLK_ENABLE_L, ... CLK_ENABLE_W
401 */
402static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32];
403
404#define clk_writel(value, reg) \
405 __raw_writel(value, reg_clk_base + (reg))
406#define clk_readl(reg) \
407 __raw_readl(reg_clk_base + (reg))
408#define pmc_writel(value, reg) \
409 __raw_writel(value, reg_pmc_base + (reg))
410#define pmc_readl(reg) \
411 __raw_readl(reg_pmc_base + (reg))
412#define chipid_readl() \
413 __raw_readl(misc_gp_hidrev_base + MISC_GP_HIDREV)
414
415#define clk_writel_delay(value, reg) \
416 do { \
417 __raw_writel((value), reg_clk_base + (reg)); \
418 udelay(2); \
419 } while (0)
420
421static inline int clk_set_div(struct clk_tegra *c, u32 n)
422{
423 struct clk *clk = c->hw.clk;
424
425 return clk_set_rate(clk,
426 (__clk_get_rate(__clk_get_parent(clk)) + n - 1) / n);
427}
428
429static inline u32 periph_clk_to_reg(
430 struct clk_tegra *c, u32 reg_L, u32 reg_V, int offs)
431{
432 u32 reg = c->u.periph.clk_num / 32;
433 BUG_ON(reg >= RST_DEVICES_NUM);
434 if (reg < 3)
435 reg = reg_L + (reg * offs);
436 else
437 reg = reg_V + ((reg - 3) * offs);
438 return reg;
439}
440
441static unsigned long clk_measure_input_freq(void)
442{
443 u32 clock_autodetect;
444 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
445 do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
446 clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
447 if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
448 return 12000000;
449 } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
450 return 13000000;
451 } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
452 return 19200000;
453 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
454 return 26000000;
455 } else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3) {
456 return 16800000;
457 } else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3) {
458 return 38400000;
459 } else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3) {
460 return 48000000;
461 } else {
462 pr_err("%s: Unexpected clock autodetect value %d", __func__,
463 clock_autodetect);
464 BUG();
465 return 0;
466 }
467}
468
469static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate,
470 u32 flags, u32 round_mode)
471{
472 s64 divider_u71 = parent_rate;
473 if (!rate)
474 return -EINVAL;
475
476 if (!(flags & DIV_U71_INT))
477 divider_u71 *= 2;
478 if (round_mode == ROUND_DIVIDER_UP)
479 divider_u71 += rate - 1;
480 do_div(divider_u71, rate);
481 if (flags & DIV_U71_INT)
482 divider_u71 *= 2;
483
484 if (divider_u71 - 2 < 0)
485 return 0;
486
487 if (divider_u71 - 2 > 255)
488 return -EINVAL;
489
490 return divider_u71 - 2;
491}
492
493static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
494{
495 s64 divider_u16;
496
497 divider_u16 = parent_rate;
498 if (!rate)
499 return -EINVAL;
500 divider_u16 += rate - 1;
501 do_div(divider_u16, rate);
502
503 if (divider_u16 - 1 < 0)
504 return 0;
505
506 if (divider_u16 - 1 > 0xFFFF)
507 return -EINVAL;
508
509 return divider_u16 - 1;
510}
511
512static unsigned long tegra30_clk_fixed_recalc_rate(struct clk_hw *hw,
513 unsigned long parent_rate)
514{
515 return to_clk_tegra(hw)->fixed_rate;
516}
517
518struct clk_ops tegra30_clk_32k_ops = {
519 .recalc_rate = tegra30_clk_fixed_recalc_rate,
520};
521
522/* clk_m functions */
523static unsigned long tegra30_clk_m_recalc_rate(struct clk_hw *hw,
524 unsigned long parent_rate)
525{
526 if (!to_clk_tegra(hw)->fixed_rate)
527 to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq();
528 return to_clk_tegra(hw)->fixed_rate;
529}
530
531static void tegra30_clk_m_init(struct clk_hw *hw)
532{
533 u32 osc_ctrl = clk_readl(OSC_CTRL);
534 u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
535 u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
536
537 switch (to_clk_tegra(hw)->fixed_rate) {
538 case 12000000:
539 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
540 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
541 break;
542 case 13000000:
543 auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
544 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
545 break;
546 case 19200000:
547 auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
548 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
549 break;
550 case 26000000:
551 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
552 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
553 break;
554 case 16800000:
555 auto_clock_control |= OSC_CTRL_OSC_FREQ_16_8MHZ;
556 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
557 break;
558 case 38400000:
559 auto_clock_control |= OSC_CTRL_OSC_FREQ_38_4MHZ;
560 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2);
561 break;
562 case 48000000:
563 auto_clock_control |= OSC_CTRL_OSC_FREQ_48MHZ;
564 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4);
565 break;
566 default:
567 pr_err("%s: Unexpected clock rate %ld", __func__,
568 to_clk_tegra(hw)->fixed_rate);
569 BUG();
570 }
571 clk_writel(auto_clock_control, OSC_CTRL);
572}
573
574struct clk_ops tegra30_clk_m_ops = {
575 .init = tegra30_clk_m_init,
576 .recalc_rate = tegra30_clk_m_recalc_rate,
577};
578
579static unsigned long tegra30_clk_m_div_recalc_rate(struct clk_hw *hw,
580 unsigned long parent_rate)
581{
582 struct clk_tegra *c = to_clk_tegra(hw);
583 u64 rate = parent_rate;
584
585 if (c->mul != 0 && c->div != 0) {
586 rate *= c->mul;
587 rate += c->div - 1; /* round up */
588 do_div(rate, c->div);
589 }
590
591 return rate;
592}
593
594struct clk_ops tegra_clk_m_div_ops = {
595 .recalc_rate = tegra30_clk_m_div_recalc_rate,
596};
597
598/* PLL reference divider functions */
599static unsigned long tegra30_pll_ref_recalc_rate(struct clk_hw *hw,
600 unsigned long parent_rate)
601{
602 struct clk_tegra *c = to_clk_tegra(hw);
603 unsigned long rate = parent_rate;
604 u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK;
605
606 switch (pll_ref_div) {
607 case OSC_CTRL_PLL_REF_DIV_1:
608 c->div = 1;
609 break;
610 case OSC_CTRL_PLL_REF_DIV_2:
611 c->div = 2;
612 break;
613 case OSC_CTRL_PLL_REF_DIV_4:
614 c->div = 4;
615 break;
616 default:
617 pr_err("%s: Invalid pll ref divider %d", __func__, pll_ref_div);
618 BUG();
619 }
620 c->mul = 1;
621
622 if (c->mul != 0 && c->div != 0) {
623 rate *= c->mul;
624 rate += c->div - 1; /* round up */
625 do_div(rate, c->div);
626 }
627
628 return rate;
629}
630
631struct clk_ops tegra_pll_ref_ops = {
632 .recalc_rate = tegra30_pll_ref_recalc_rate,
633};
634
635/* super clock functions */
636/* "super clocks" on tegra30 have two-stage muxes, fractional 7.1 divider and
637 * clock skipping super divider. We will ignore the clock skipping divider,
638 * since we can't lower the voltage when using the clock skip, but we can if
639 * we lower the PLL frequency. We will use 7.1 divider for CPU super-clock
640 * only when its parent is a fixed rate PLL, since we can't change PLL rate
641 * in this case.
642 */
643static void tegra30_super_clk_init(struct clk_hw *hw)
644{
645 struct clk_tegra *c = to_clk_tegra(hw);
646 struct clk_tegra *p =
647 to_clk_tegra(__clk_get_hw(__clk_get_parent(hw->clk)));
648
649 c->state = ON;
650 if (c->flags & DIV_U71) {
651 /* Init safe 7.1 divider value (does not affect PLLX path) */
652 clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT,
653 c->reg + SUPER_CLK_DIVIDER);
654 c->mul = 2;
655 c->div = 2;
656 if (!(p->flags & PLLX))
657 c->div += SUPER_CLOCK_DIV_U71_MIN;
658 } else
659 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
660}
661
662static u8 tegra30_super_clk_get_parent(struct clk_hw *hw)
663{
664 struct clk_tegra *c = to_clk_tegra(hw);
665 u32 val;
666 int source;
667 int shift;
668
669 val = clk_readl(c->reg + SUPER_CLK_MUX);
670 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
671 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
672 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
673 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
674 source = (val >> shift) & SUPER_SOURCE_MASK;
675 if (c->flags & DIV_2)
676 source |= val & SUPER_LP_DIV2_BYPASS;
677
678 return source;
679}
680
681static int tegra30_super_clk_set_parent(struct clk_hw *hw, u8 index)
682{
683 struct clk_tegra *c = to_clk_tegra(hw);
684 struct clk_tegra *p =
685 to_clk_tegra(__clk_get_hw(clk_get_parent(hw->clk)));
686 u32 val;
687 int shift;
688
689 val = clk_readl(c->reg + SUPER_CLK_MUX);
690 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
691 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
692 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
693 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
694
695 /* For LP mode super-clock switch between PLLX direct
696 and divided-by-2 outputs is allowed only when other
697 than PLLX clock source is current parent */
698 if ((c->flags & DIV_2) && (p->flags & PLLX) &&
699 ((index ^ val) & SUPER_LP_DIV2_BYPASS)) {
700 if (p->flags & PLLX)
701 return -EINVAL;
702 val ^= SUPER_LP_DIV2_BYPASS;
703 clk_writel_delay(val, c->reg);
704 }
705 val &= ~(SUPER_SOURCE_MASK << shift);
706 val |= (index & SUPER_SOURCE_MASK) << shift;
707
708 /* 7.1 divider for CPU super-clock does not affect
709 PLLX path */
710 if (c->flags & DIV_U71) {
711 u32 div = 0;
712 if (!(p->flags & PLLX)) {
713 div = clk_readl(c->reg +
714 SUPER_CLK_DIVIDER);
715 div &= SUPER_CLOCK_DIV_U71_MASK;
716 div >>= SUPER_CLOCK_DIV_U71_SHIFT;
717 }
718 c->div = div + 2;
719 c->mul = 2;
720 }
721 clk_writel_delay(val, c->reg);
722
723 return 0;
724}
725
726/*
727 * Do not use super clocks "skippers", since dividing using a clock skipper
728 * does not allow the voltage to be scaled down. Instead adjust the rate of
729 * the parent clock. This requires that the parent of a super clock have no
730 * other children, otherwise the rate will change underneath the other
731 * children. Special case: if fixed rate PLL is CPU super clock parent the
732 * rate of this PLL can't be changed, and it has many other children. In
733 * this case use 7.1 fractional divider to adjust the super clock rate.
734 */
735static int tegra30_super_clk_set_rate(struct clk_hw *hw, unsigned long rate,
736 unsigned long parent_rate)
737{
738 struct clk_tegra *c = to_clk_tegra(hw);
739 struct clk *parent = __clk_get_parent(hw->clk);
740 struct clk_tegra *cparent = to_clk_tegra(__clk_get_hw(parent));
741
742 if ((c->flags & DIV_U71) && (cparent->flags & PLL_FIXED)) {
743 int div = clk_div71_get_divider(parent_rate,
744 rate, c->flags, ROUND_DIVIDER_DOWN);
745 div = max(div, SUPER_CLOCK_DIV_U71_MIN);
746
747 clk_writel(div << SUPER_CLOCK_DIV_U71_SHIFT,
748 c->reg + SUPER_CLK_DIVIDER);
749 c->div = div + 2;
750 c->mul = 2;
751 return 0;
752 }
753 return 0;
754}
755
756static unsigned long tegra30_super_clk_recalc_rate(struct clk_hw *hw,
757 unsigned long parent_rate)
758{
759 struct clk_tegra *c = to_clk_tegra(hw);
760 u64 rate = parent_rate;
761
762 if (c->mul != 0 && c->div != 0) {
763 rate *= c->mul;
764 rate += c->div - 1; /* round up */
765 do_div(rate, c->div);
766 }
767
768 return rate;
769}
770
771static long tegra30_super_clk_round_rate(struct clk_hw *hw, unsigned long rate,
772 unsigned long *prate)
773{
774 struct clk_tegra *c = to_clk_tegra(hw);
775 struct clk *parent = __clk_get_parent(hw->clk);
776 struct clk_tegra *cparent = to_clk_tegra(__clk_get_hw(parent));
777 int mul = 2;
778 int div;
779
780 if ((c->flags & DIV_U71) && (cparent->flags & PLL_FIXED)) {
781 div = clk_div71_get_divider(*prate,
782 rate, c->flags, ROUND_DIVIDER_DOWN);
783 div = max(div, SUPER_CLOCK_DIV_U71_MIN) + 2;
784 rate = *prate * mul;
785 rate += div - 1; /* round up */
786 do_div(rate, c->div);
787
788 return rate;
789 }
790 return *prate;
791}
792
793struct clk_ops tegra30_super_ops = {
794 .init = tegra30_super_clk_init,
795 .set_parent = tegra30_super_clk_set_parent,
796 .get_parent = tegra30_super_clk_get_parent,
797 .recalc_rate = tegra30_super_clk_recalc_rate,
798 .round_rate = tegra30_super_clk_round_rate,
799 .set_rate = tegra30_super_clk_set_rate,
800};
801
802static unsigned long tegra30_twd_clk_recalc_rate(struct clk_hw *hw,
803 unsigned long parent_rate)
804{
805 struct clk_tegra *c = to_clk_tegra(hw);
806 u64 rate = parent_rate;
807
808 if (c->mul != 0 && c->div != 0) {
809 rate *= c->mul;
810 rate += c->div - 1; /* round up */
811 do_div(rate, c->div);
812 }
813
814 return rate;
815}
816
817struct clk_ops tegra30_twd_ops = {
818 .recalc_rate = tegra30_twd_clk_recalc_rate,
819};
820
821/* bus clock functions */
822static int tegra30_bus_clk_is_enabled(struct clk_hw *hw)
823{
824 struct clk_tegra *c = to_clk_tegra(hw);
825 u32 val = clk_readl(c->reg);
826
827 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
828 return c->state;
829}
830
831static int tegra30_bus_clk_enable(struct clk_hw *hw)
832{
833 struct clk_tegra *c = to_clk_tegra(hw);
834 u32 val;
835
836 val = clk_readl(c->reg);
837 val &= ~(BUS_CLK_DISABLE << c->reg_shift);
838 clk_writel(val, c->reg);
839
840 return 0;
841}
842
843static void tegra30_bus_clk_disable(struct clk_hw *hw)
844{
845 struct clk_tegra *c = to_clk_tegra(hw);
846 u32 val;
847
848 val = clk_readl(c->reg);
849 val |= BUS_CLK_DISABLE << c->reg_shift;
850 clk_writel(val, c->reg);
851}
852
853static unsigned long tegra30_bus_clk_recalc_rate(struct clk_hw *hw,
854 unsigned long prate)
855{
856 struct clk_tegra *c = to_clk_tegra(hw);
857 u32 val = clk_readl(c->reg);
858 u64 rate = prate;
859
860 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
861 c->mul = 1;
862
863 if (c->mul != 0 && c->div != 0) {
864 rate *= c->mul;
865 rate += c->div - 1; /* round up */
866 do_div(rate, c->div);
867 }
868 return rate;
869}
870
871static int tegra30_bus_clk_set_rate(struct clk_hw *hw, unsigned long rate,
872 unsigned long parent_rate)
873{
874 struct clk_tegra *c = to_clk_tegra(hw);
875 int ret = -EINVAL;
876 u32 val;
877 int i;
878
879 val = clk_readl(c->reg);
880 for (i = 1; i <= 4; i++) {
881 if (rate == parent_rate / i) {
882 val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
883 val |= (i - 1) << c->reg_shift;
884 clk_writel(val, c->reg);
885 c->div = i;
886 c->mul = 1;
887 ret = 0;
888 break;
889 }
890 }
891
892 return ret;
893}
894
895static long tegra30_bus_clk_round_rate(struct clk_hw *hw, unsigned long rate,
896 unsigned long *prate)
897{
898 unsigned long parent_rate = *prate;
899 s64 divider;
900
901 if (rate >= parent_rate)
902 return parent_rate;
903
904 divider = parent_rate;
905 divider += rate - 1;
906 do_div(divider, rate);
907
908 if (divider < 0)
909 return divider;
910
911 if (divider > 4)
912 divider = 4;
913 do_div(parent_rate, divider);
914
915 return parent_rate;
916}
917
918struct clk_ops tegra30_bus_ops = {
919 .is_enabled = tegra30_bus_clk_is_enabled,
920 .enable = tegra30_bus_clk_enable,
921 .disable = tegra30_bus_clk_disable,
922 .set_rate = tegra30_bus_clk_set_rate,
923 .round_rate = tegra30_bus_clk_round_rate,
924 .recalc_rate = tegra30_bus_clk_recalc_rate,
925};
926
927/* Blink output functions */
928static int tegra30_blink_clk_is_enabled(struct clk_hw *hw)
929{
930 struct clk_tegra *c = to_clk_tegra(hw);
931 u32 val;
932
933 val = pmc_readl(PMC_CTRL);
934 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
935 return c->state;
936}
937
938static int tegra30_blink_clk_enable(struct clk_hw *hw)
939{
940 u32 val;
941
942 val = pmc_readl(PMC_DPD_PADS_ORIDE);
943 pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
944
945 val = pmc_readl(PMC_CTRL);
946 pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
947
948 return 0;
949}
950
951static void tegra30_blink_clk_disable(struct clk_hw *hw)
952{
953 u32 val;
954
955 val = pmc_readl(PMC_CTRL);
956 pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
957
958 val = pmc_readl(PMC_DPD_PADS_ORIDE);
959 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
960}
961
962static int tegra30_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate,
963 unsigned long parent_rate)
964{
965 struct clk_tegra *c = to_clk_tegra(hw);
966
967 if (rate >= parent_rate) {
968 c->div = 1;
969 pmc_writel(0, c->reg);
970 } else {
971 unsigned int on_off;
972 u32 val;
973
974 on_off = DIV_ROUND_UP(parent_rate / 8, rate);
975 c->div = on_off * 8;
976
977 val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
978 PMC_BLINK_TIMER_DATA_ON_SHIFT;
979 on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
980 on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
981 val |= on_off;
982 val |= PMC_BLINK_TIMER_ENB;
983 pmc_writel(val, c->reg);
984 }
985
986 return 0;
987}
988
989static unsigned long tegra30_blink_clk_recalc_rate(struct clk_hw *hw,
990 unsigned long parent_rate)
991{
992 struct clk_tegra *c = to_clk_tegra(hw);
993 u64 rate = parent_rate;
994 u32 val;
995 u32 mul;
996 u32 div;
997 u32 on_off;
998
999 mul = 1;
1000 val = pmc_readl(c->reg);
1001
1002 if (val & PMC_BLINK_TIMER_ENB) {
1003 on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
1004 PMC_BLINK_TIMER_DATA_ON_MASK;
1005 val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
1006 val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
1007 on_off += val;
1008 /* each tick in the blink timer is 4 32KHz clocks */
1009 div = on_off * 4;
1010 } else {
1011 div = 1;
1012 }
1013
1014 if (mul != 0 && div != 0) {
1015 rate *= mul;
1016 rate += div - 1; /* round up */
1017 do_div(rate, div);
1018 }
1019 return rate;
1020}
1021
1022static long tegra30_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1023 unsigned long *prate)
1024{
1025 int div;
1026 int mul;
1027 long round_rate = *prate;
1028
1029 mul = 1;
1030
1031 if (rate >= *prate) {
1032 div = 1;
1033 } else {
1034 div = DIV_ROUND_UP(*prate / 8, rate);
1035 div *= 8;
1036 }
1037
1038 round_rate *= mul;
1039 round_rate += div - 1;
1040 do_div(round_rate, div);
1041
1042 return round_rate;
1043}
1044
1045struct clk_ops tegra30_blink_clk_ops = {
1046 .is_enabled = tegra30_blink_clk_is_enabled,
1047 .enable = tegra30_blink_clk_enable,
1048 .disable = tegra30_blink_clk_disable,
1049 .recalc_rate = tegra30_blink_clk_recalc_rate,
1050 .round_rate = tegra30_blink_clk_round_rate,
1051 .set_rate = tegra30_blink_clk_set_rate,
1052};
1053
1054static void tegra30_utmi_param_configure(struct clk_hw *hw)
1055{
1056 unsigned long main_rate =
1057 __clk_get_rate(__clk_get_parent(__clk_get_parent(hw->clk)));
1058 u32 reg;
1059 int i;
1060
1061 for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
1062 if (main_rate == utmi_parameters[i].osc_frequency)
1063 break;
1064 }
1065
1066 if (i >= ARRAY_SIZE(utmi_parameters)) {
1067 pr_err("%s: Unexpected main rate %lu\n", __func__, main_rate);
1068 return;
1069 }
1070
1071 reg = clk_readl(UTMIP_PLL_CFG2);
1072
1073 /* Program UTMIP PLL stable and active counts */
1074 /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
1075 reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
1076 reg |= UTMIP_PLL_CFG2_STABLE_COUNT(
1077 utmi_parameters[i].stable_count);
1078
1079 reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
1080
1081 reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(
1082 utmi_parameters[i].active_delay_count);
1083
1084 /* Remove power downs from UTMIP PLL control bits */
1085 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
1086 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
1087 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
1088
1089 clk_writel(reg, UTMIP_PLL_CFG2);
1090
1091 /* Program UTMIP PLL delay and oscillator frequency counts */
1092 reg = clk_readl(UTMIP_PLL_CFG1);
1093 reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
1094
1095 reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(
1096 utmi_parameters[i].enable_delay_count);
1097
1098 reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
1099 reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(
1100 utmi_parameters[i].xtal_freq_count);
1101
1102 /* Remove power downs from UTMIP PLL control bits */
1103 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
1104 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
1105 reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
1106
1107 clk_writel(reg, UTMIP_PLL_CFG1);
1108}
1109
1110/* PLL Functions */
1111static int tegra30_pll_clk_wait_for_lock(struct clk_tegra *c, u32 lock_reg,
1112 u32 lock_bit)
1113{
1114 int ret = 0;
1115
1116#if USE_PLL_LOCK_BITS
1117 int i;
1118 for (i = 0; i < c->u.pll.lock_delay; i++) {
1119 if (clk_readl(lock_reg) & lock_bit) {
1120 udelay(PLL_POST_LOCK_DELAY);
1121 return 0;
1122 }
1123 udelay(2); /* timeout = 2 * lock time */
1124 }
1125 pr_err("Timed out waiting for lock bit on pll %s",
1126 __clk_get_name(hw->clk));
1127 ret = -1;
1128#else
1129 udelay(c->u.pll.lock_delay);
1130#endif
1131 return ret;
1132}
1133
1134static int tegra30_pll_clk_is_enabled(struct clk_hw *hw)
1135{
1136 struct clk_tegra *c = to_clk_tegra(hw);
1137 u32 val = clk_readl(c->reg + PLL_BASE);
1138
1139 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
1140 return c->state;
1141}
1142
1143static void tegra30_pll_clk_init(struct clk_hw *hw)
1144{
1145 struct clk_tegra *c = to_clk_tegra(hw);
1146
1147 if (c->flags & PLLU)
1148 tegra30_utmi_param_configure(hw);
1149}
1150
1151static int tegra30_pll_clk_enable(struct clk_hw *hw)
1152{
1153 struct clk_tegra *c = to_clk_tegra(hw);
1154 u32 val;
1155 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
1156
1157#if USE_PLL_LOCK_BITS
1158 val = clk_readl(c->reg + PLL_MISC(c));
1159 val |= PLL_MISC_LOCK_ENABLE(c);
1160 clk_writel(val, c->reg + PLL_MISC(c));
1161#endif
1162 val = clk_readl(c->reg + PLL_BASE);
1163 val &= ~PLL_BASE_BYPASS;
1164 val |= PLL_BASE_ENABLE;
1165 clk_writel(val, c->reg + PLL_BASE);
1166
1167 if (c->flags & PLLM) {
1168 val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
1169 val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
1170 pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
1171 }
1172
1173 tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_BASE, PLL_BASE_LOCK);
1174
1175 return 0;
1176}
1177
1178static void tegra30_pll_clk_disable(struct clk_hw *hw)
1179{
1180 struct clk_tegra *c = to_clk_tegra(hw);
1181 u32 val;
1182 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
1183
1184 val = clk_readl(c->reg);
1185 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
1186 clk_writel(val, c->reg);
1187
1188 if (c->flags & PLLM) {
1189 val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
1190 val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
1191 pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
1192 }
1193}
1194
1195static int tegra30_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1196 unsigned long parent_rate)
1197{
1198 struct clk_tegra *c = to_clk_tegra(hw);
1199 u32 val, p_div, old_base;
1200 unsigned long input_rate;
1201 const struct clk_pll_freq_table *sel;
1202 struct clk_pll_freq_table cfg;
1203
1204 if (c->flags & PLL_FIXED) {
1205 int ret = 0;
1206 if (rate != c->u.pll.fixed_rate) {
1207 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
1208 __func__, __clk_get_name(hw->clk),
1209 c->u.pll.fixed_rate, rate);
1210 ret = -EINVAL;
1211 }
1212 return ret;
1213 }
1214
1215 if (c->flags & PLLM) {
1216 if (rate != __clk_get_rate(hw->clk)) {
1217 pr_err("%s: Can not change memory %s rate in flight\n",
1218 __func__, __clk_get_name(hw->clk));
1219 return -EINVAL;
1220 }
1221 }
1222
1223 p_div = 0;
1224 input_rate = parent_rate;
1225
1226 /* Check if the target rate is tabulated */
1227 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1228 if (sel->input_rate == input_rate && sel->output_rate == rate) {
1229 if (c->flags & PLLU) {
1230 BUG_ON(sel->p < 1 || sel->p > 2);
1231 if (sel->p == 1)
1232 p_div = PLLU_BASE_POST_DIV;
1233 } else {
1234 BUG_ON(sel->p < 1);
1235 for (val = sel->p; val > 1; val >>= 1)
1236 p_div++;
1237 p_div <<= PLL_BASE_DIVP_SHIFT;
1238 }
1239 break;
1240 }
1241 }
1242
1243 /* Configure out-of-table rate */
1244 if (sel->input_rate == 0) {
1245 unsigned long cfreq;
1246 BUG_ON(c->flags & PLLU);
1247 sel = &cfg;
1248
1249 switch (input_rate) {
1250 case 12000000:
1251 case 26000000:
1252 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
1253 break;
1254 case 13000000:
1255 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
1256 break;
1257 case 16800000:
1258 case 19200000:
1259 cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
1260 break;
1261 default:
1262 pr_err("%s: Unexpected reference rate %lu\n",
1263 __func__, input_rate);
1264 BUG();
1265 }
1266
1267 /* Raise VCO to guarantee 0.5% accuracy */
1268 for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq;
1269 cfg.output_rate <<= 1)
1270 p_div++;
1271
1272 cfg.p = 0x1 << p_div;
1273 cfg.m = input_rate / cfreq;
1274 cfg.n = cfg.output_rate / cfreq;
1275 cfg.cpcon = OUT_OF_TABLE_CPCON;
1276
1277 if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) ||
1278 (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) ||
1279 (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) ||
1280 (cfg.output_rate > c->u.pll.vco_max)) {
1281 pr_err("%s: Failed to set %s out-of-table rate %lu\n",
1282 __func__, __clk_get_name(hw->clk), rate);
1283 return -EINVAL;
1284 }
1285 p_div <<= PLL_BASE_DIVP_SHIFT;
1286 }
1287
1288 c->mul = sel->n;
1289 c->div = sel->m * sel->p;
1290
1291 old_base = val = clk_readl(c->reg + PLL_BASE);
1292 val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK |
1293 ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK));
1294 val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
1295 (sel->n << PLL_BASE_DIVN_SHIFT) | p_div;
1296 if (val == old_base)
1297 return 0;
1298
1299 if (c->state == ON) {
1300 tegra30_pll_clk_disable(hw);
1301 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
1302 }
1303 clk_writel(val, c->reg + PLL_BASE);
1304
1305 if (c->flags & PLL_HAS_CPCON) {
1306 val = clk_readl(c->reg + PLL_MISC(c));
1307 val &= ~PLL_MISC_CPCON_MASK;
1308 val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
1309 if (c->flags & (PLLU | PLLD)) {
1310 val &= ~PLL_MISC_LFCON_MASK;
1311 if (sel->n >= PLLDU_LFCON_SET_DIVN)
1312 val |= 0x1 << PLL_MISC_LFCON_SHIFT;
1313 } else if (c->flags & (PLLX | PLLM)) {
1314 val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
1315 if (rate >= (c->u.pll.vco_max >> 1))
1316 val |= 0x1 << PLL_MISC_DCCON_SHIFT;
1317 }
1318 clk_writel(val, c->reg + PLL_MISC(c));
1319 }
1320
1321 if (c->state == ON)
1322 tegra30_pll_clk_enable(hw);
1323
1324 c->u.pll.fixed_rate = rate;
1325
1326 return 0;
1327}
1328
1329static long tegra30_pll_round_rate(struct clk_hw *hw, unsigned long rate,
1330 unsigned long *prate)
1331{
1332 struct clk_tegra *c = to_clk_tegra(hw);
1333 unsigned long input_rate = *prate;
1334 u64 output_rate = *prate;
1335 const struct clk_pll_freq_table *sel;
1336 struct clk_pll_freq_table cfg;
1337 int mul;
1338 int div;
1339 u32 p_div;
1340 u32 val;
1341
1342 if (c->flags & PLL_FIXED)
1343 return c->u.pll.fixed_rate;
1344
1345 if (c->flags & PLLM)
1346 return __clk_get_rate(hw->clk);
1347
1348 p_div = 0;
1349 /* Check if the target rate is tabulated */
1350 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1351 if (sel->input_rate == input_rate && sel->output_rate == rate) {
1352 if (c->flags & PLLU) {
1353 BUG_ON(sel->p < 1 || sel->p > 2);
1354 if (sel->p == 1)
1355 p_div = PLLU_BASE_POST_DIV;
1356 } else {
1357 BUG_ON(sel->p < 1);
1358 for (val = sel->p; val > 1; val >>= 1)
1359 p_div++;
1360 p_div <<= PLL_BASE_DIVP_SHIFT;
1361 }
1362 break;
1363 }
1364 }
1365
1366 if (sel->input_rate == 0) {
1367 unsigned long cfreq;
1368 BUG_ON(c->flags & PLLU);
1369 sel = &cfg;
1370
1371 switch (input_rate) {
1372 case 12000000:
1373 case 26000000:
1374 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
1375 break;
1376 case 13000000:
1377 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
1378 break;
1379 case 16800000:
1380 case 19200000:
1381 cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
1382 break;
1383 default:
1384 pr_err("%s: Unexpected reference rate %lu\n",
1385 __func__, input_rate);
1386 BUG();
1387 }
1388
1389 /* Raise VCO to guarantee 0.5% accuracy */
1390 for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq;
1391 cfg.output_rate <<= 1)
1392 p_div++;
1393
1394 cfg.p = 0x1 << p_div;
1395 cfg.m = input_rate / cfreq;
1396 cfg.n = cfg.output_rate / cfreq;
1397 }
1398
1399 mul = sel->n;
1400 div = sel->m * sel->p;
1401
1402 output_rate *= mul;
1403 output_rate += div - 1; /* round up */
1404 do_div(output_rate, div);
1405
1406 return output_rate;
1407}
1408
1409static unsigned long tegra30_pll_recalc_rate(struct clk_hw *hw,
1410 unsigned long parent_rate)
1411{
1412 struct clk_tegra *c = to_clk_tegra(hw);
1413 u64 rate = parent_rate;
1414 u32 val = clk_readl(c->reg + PLL_BASE);
1415
1416 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
1417 const struct clk_pll_freq_table *sel;
1418 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1419 if (sel->input_rate == parent_rate &&
1420 sel->output_rate == c->u.pll.fixed_rate) {
1421 c->mul = sel->n;
1422 c->div = sel->m * sel->p;
1423 break;
1424 }
1425 }
1426 pr_err("Clock %s has unknown fixed frequency\n",
1427 __clk_get_name(hw->clk));
1428 BUG();
1429 } else if (val & PLL_BASE_BYPASS) {
1430 c->mul = 1;
1431 c->div = 1;
1432 } else {
1433 c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
1434 c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
1435 if (c->flags & PLLU)
1436 c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
1437 else
1438 c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >>
1439 PLL_BASE_DIVP_SHIFT));
1440 }
1441
1442 if (c->mul != 0 && c->div != 0) {
1443 rate *= c->mul;
1444 rate += c->div - 1; /* round up */
1445 do_div(rate, c->div);
1446 }
1447
1448 return rate;
1449}
1450
1451struct clk_ops tegra30_pll_ops = {
1452 .is_enabled = tegra30_pll_clk_is_enabled,
1453 .init = tegra30_pll_clk_init,
1454 .enable = tegra30_pll_clk_enable,
1455 .disable = tegra30_pll_clk_disable,
1456 .recalc_rate = tegra30_pll_recalc_rate,
1457 .round_rate = tegra30_pll_round_rate,
1458 .set_rate = tegra30_pll_clk_set_rate,
1459};
1460
1461int tegra30_plld_clk_cfg_ex(struct clk_hw *hw,
1462 enum tegra_clk_ex_param p, u32 setting)
1463{
1464 struct clk_tegra *c = to_clk_tegra(hw);
1465 u32 val, mask, reg;
1466
1467 switch (p) {
1468 case TEGRA_CLK_PLLD_CSI_OUT_ENB:
1469 mask = PLLD_BASE_CSI_CLKENABLE;
1470 reg = c->reg + PLL_BASE;
1471 break;
1472 case TEGRA_CLK_PLLD_DSI_OUT_ENB:
1473 mask = PLLD_MISC_DSI_CLKENABLE;
1474 reg = c->reg + PLL_MISC(c);
1475 break;
1476 case TEGRA_CLK_PLLD_MIPI_MUX_SEL:
1477 if (!(c->flags & PLL_ALT_MISC_REG)) {
1478 mask = PLLD_BASE_DSIB_MUX_MASK;
1479 reg = c->reg + PLL_BASE;
1480 break;
1481 }
1482 /* fall through - error since PLLD2 does not have MUX_SEL control */
1483 default:
1484 return -EINVAL;
1485 }
1486
1487 val = clk_readl(reg);
1488 if (setting)
1489 val |= mask;
1490 else
1491 val &= ~mask;
1492 clk_writel(val, reg);
1493 return 0;
1494}
1495
1496static int tegra30_plle_clk_is_enabled(struct clk_hw *hw)
1497{
1498 struct clk_tegra *c = to_clk_tegra(hw);
1499 u32 val;
1500
1501 val = clk_readl(c->reg + PLL_BASE);
1502 c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF;
1503 return c->state;
1504}
1505
1506static void tegra30_plle_clk_disable(struct clk_hw *hw)
1507{
1508 struct clk_tegra *c = to_clk_tegra(hw);
1509 u32 val;
1510
1511 val = clk_readl(c->reg + PLL_BASE);
1512 val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
1513 clk_writel(val, c->reg + PLL_BASE);
1514}
1515
1516static void tegra30_plle_training(struct clk_tegra *c)
1517{
1518 u32 val;
1519
1520 /* PLLE is already disabled, and setup cleared;
1521 * create falling edge on PLLE IDDQ input */
1522 val = pmc_readl(PMC_SATA_PWRGT);
1523 val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
1524 pmc_writel(val, PMC_SATA_PWRGT);
1525
1526 val = pmc_readl(PMC_SATA_PWRGT);
1527 val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
1528 pmc_writel(val, PMC_SATA_PWRGT);
1529
1530 val = pmc_readl(PMC_SATA_PWRGT);
1531 val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
1532 pmc_writel(val, PMC_SATA_PWRGT);
1533
1534 do {
1535 val = clk_readl(c->reg + PLL_MISC(c));
1536 } while (!(val & PLLE_MISC_READY));
1537}
1538
1539static int tegra30_plle_configure(struct clk_hw *hw, bool force_training)
1540{
1541 struct clk_tegra *c = to_clk_tegra(hw);
1542 struct clk *parent = __clk_get_parent(hw->clk);
1543 const struct clk_pll_freq_table *sel;
1544 u32 val;
1545
1546 unsigned long rate = c->u.pll.fixed_rate;
1547 unsigned long input_rate = __clk_get_rate(parent);
1548
1549 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
1550 if (sel->input_rate == input_rate && sel->output_rate == rate)
1551 break;
1552 }
1553
1554 if (sel->input_rate == 0)
1555 return -ENOSYS;
1556
1557 /* disable PLLE, clear setup fiels */
1558 tegra30_plle_clk_disable(hw);
1559
1560 val = clk_readl(c->reg + PLL_MISC(c));
1561 val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
1562 clk_writel(val, c->reg + PLL_MISC(c));
1563
1564 /* training */
1565 val = clk_readl(c->reg + PLL_MISC(c));
1566 if (force_training || (!(val & PLLE_MISC_READY)))
1567 tegra30_plle_training(c);
1568
1569 /* configure dividers, setup, disable SS */
1570 val = clk_readl(c->reg + PLL_BASE);
1571 val &= ~PLLE_BASE_DIV_MASK;
1572 val |= PLLE_BASE_DIV(sel->m, sel->n, sel->p, sel->cpcon);
1573 clk_writel(val, c->reg + PLL_BASE);
1574 c->mul = sel->n;
1575 c->div = sel->m * sel->p;
1576
1577 val = clk_readl(c->reg + PLL_MISC(c));
1578 val |= PLLE_MISC_SETUP_VALUE;
1579 val |= PLLE_MISC_LOCK_ENABLE;
1580 clk_writel(val, c->reg + PLL_MISC(c));
1581
1582 val = clk_readl(PLLE_SS_CTRL);
1583 val |= PLLE_SS_DISABLE;
1584 clk_writel(val, PLLE_SS_CTRL);
1585
1586 /* enable and lock PLLE*/
1587 val = clk_readl(c->reg + PLL_BASE);
1588 val |= (PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
1589 clk_writel(val, c->reg + PLL_BASE);
1590
1591 tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_MISC(c), PLLE_MISC_LOCK);
1592
1593 return 0;
1594}
1595
1596static int tegra30_plle_clk_enable(struct clk_hw *hw)
1597{
1598 struct clk_tegra *c = to_clk_tegra(hw);
1599
1600 return tegra30_plle_configure(hw, !c->set);
1601}
1602
1603static unsigned long tegra30_plle_clk_recalc_rate(struct clk_hw *hw,
1604 unsigned long parent_rate)
1605{
1606 struct clk_tegra *c = to_clk_tegra(hw);
1607 unsigned long rate = parent_rate;
1608 u32 val;
1609
1610 val = clk_readl(c->reg + PLL_BASE);
1611 c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT;
1612 c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT;
1613 c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT;
1614
1615 if (c->mul != 0 && c->div != 0) {
1616 rate *= c->mul;
1617 rate += c->div - 1; /* round up */
1618 do_div(rate, c->div);
1619 }
1620 return rate;
1621}
1622
1623struct clk_ops tegra30_plle_ops = {
1624 .is_enabled = tegra30_plle_clk_is_enabled,
1625 .enable = tegra30_plle_clk_enable,
1626 .disable = tegra30_plle_clk_disable,
1627 .recalc_rate = tegra30_plle_clk_recalc_rate,
1628};
1629
1630/* Clock divider ops */
1631static int tegra30_pll_div_clk_is_enabled(struct clk_hw *hw)
1632{
1633 struct clk_tegra *c = to_clk_tegra(hw);
1634
1635 if (c->flags & DIV_U71) {
1636 u32 val = clk_readl(c->reg);
1637 val >>= c->reg_shift;
1638 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
1639 if (!(val & PLL_OUT_RESET_DISABLE))
1640 c->state = OFF;
1641 } else {
1642 c->state = ON;
1643 }
1644 return c->state;
1645}
1646
1647static int tegra30_pll_div_clk_enable(struct clk_hw *hw)
1648{
1649 struct clk_tegra *c = to_clk_tegra(hw);
1650 u32 val;
1651 u32 new_val;
1652
1653 pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
1654 if (c->flags & DIV_U71) {
1655 val = clk_readl(c->reg);
1656 new_val = val >> c->reg_shift;
1657 new_val &= 0xFFFF;
1658
1659 new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
1660
1661 val &= ~(0xFFFF << c->reg_shift);
1662 val |= new_val << c->reg_shift;
1663 clk_writel_delay(val, c->reg);
1664 return 0;
1665 } else if (c->flags & DIV_2) {
1666 return 0;
1667 }
1668 return -EINVAL;
1669}
1670
1671static void tegra30_pll_div_clk_disable(struct clk_hw *hw)
1672{
1673 struct clk_tegra *c = to_clk_tegra(hw);
1674 u32 val;
1675 u32 new_val;
1676
1677 pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
1678 if (c->flags & DIV_U71) {
1679 val = clk_readl(c->reg);
1680 new_val = val >> c->reg_shift;
1681 new_val &= 0xFFFF;
1682
1683 new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
1684
1685 val &= ~(0xFFFF << c->reg_shift);
1686 val |= new_val << c->reg_shift;
1687 clk_writel_delay(val, c->reg);
1688 }
1689}
1690
1691static int tegra30_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1692 unsigned long parent_rate)
1693{
1694 struct clk_tegra *c = to_clk_tegra(hw);
1695 u32 val;
1696 u32 new_val;
1697 int divider_u71;
1698
1699 if (c->flags & DIV_U71) {
1700 divider_u71 = clk_div71_get_divider(
1701 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1702 if (divider_u71 >= 0) {
1703 val = clk_readl(c->reg);
1704 new_val = val >> c->reg_shift;
1705 new_val &= 0xFFFF;
1706 if (c->flags & DIV_U71_FIXED)
1707 new_val |= PLL_OUT_OVERRIDE;
1708 new_val &= ~PLL_OUT_RATIO_MASK;
1709 new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
1710
1711 val &= ~(0xFFFF << c->reg_shift);
1712 val |= new_val << c->reg_shift;
1713 clk_writel_delay(val, c->reg);
1714 c->div = divider_u71 + 2;
1715 c->mul = 2;
1716 c->fixed_rate = rate;
1717 return 0;
1718 }
1719 } else if (c->flags & DIV_2) {
1720 c->fixed_rate = rate;
1721 return 0;
1722 }
1723
1724 return -EINVAL;
1725}
1726
1727static unsigned long tegra30_pll_div_clk_recalc_rate(struct clk_hw *hw,
1728 unsigned long parent_rate)
1729{
1730 struct clk_tegra *c = to_clk_tegra(hw);
1731 u64 rate = parent_rate;
1732
1733 if (c->flags & DIV_U71) {
1734 u32 divu71;
1735 u32 val = clk_readl(c->reg);
1736 val >>= c->reg_shift;
1737
1738 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
1739 c->div = (divu71 + 2);
1740 c->mul = 2;
1741 } else if (c->flags & DIV_2) {
1742 if (c->flags & (PLLD | PLLX)) {
1743 c->div = 2;
1744 c->mul = 1;
1745 } else
1746 BUG();
1747 } else {
1748 c->div = 1;
1749 c->mul = 1;
1750 }
1751 if (c->mul != 0 && c->div != 0) {
1752 rate *= c->mul;
1753 rate += c->div - 1; /* round up */
1754 do_div(rate, c->div);
1755 }
1756
1757 return rate;
1758}
1759
1760static long tegra30_pll_div_clk_round_rate(struct clk_hw *hw,
1761 unsigned long rate, unsigned long *prate)
1762{
1763 struct clk_tegra *c = to_clk_tegra(hw);
1764 unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
1765 int divider;
1766
1767 if (prate)
1768 parent_rate = *prate;
1769
1770 if (c->flags & DIV_U71) {
1771 divider = clk_div71_get_divider(
1772 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1773 if (divider < 0)
1774 return divider;
1775 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1776 } else if (c->flags & DIV_2) {
1777 *prate = rate * 2;
1778 return rate;
1779 }
1780
1781 return -EINVAL;
1782}
1783
1784struct clk_ops tegra30_pll_div_ops = {
1785 .is_enabled = tegra30_pll_div_clk_is_enabled,
1786 .enable = tegra30_pll_div_clk_enable,
1787 .disable = tegra30_pll_div_clk_disable,
1788 .set_rate = tegra30_pll_div_clk_set_rate,
1789 .recalc_rate = tegra30_pll_div_clk_recalc_rate,
1790 .round_rate = tegra30_pll_div_clk_round_rate,
1791};
1792
1793/* Periph clk ops */
1794static inline u32 periph_clk_source_mask(struct clk_tegra *c)
1795{
1796 if (c->flags & MUX8)
1797 return 7 << 29;
1798 else if (c->flags & MUX_PWM)
1799 return 3 << 28;
1800 else if (c->flags & MUX_CLK_OUT)
1801 return 3 << (c->u.periph.clk_num + 4);
1802 else if (c->flags & PLLD)
1803 return PLLD_BASE_DSIB_MUX_MASK;
1804 else
1805 return 3 << 30;
1806}
1807
1808static inline u32 periph_clk_source_shift(struct clk_tegra *c)
1809{
1810 if (c->flags & MUX8)
1811 return 29;
1812 else if (c->flags & MUX_PWM)
1813 return 28;
1814 else if (c->flags & MUX_CLK_OUT)
1815 return c->u.periph.clk_num + 4;
1816 else if (c->flags & PLLD)
1817 return PLLD_BASE_DSIB_MUX_SHIFT;
1818 else
1819 return 30;
1820}
1821
1822static int tegra30_periph_clk_is_enabled(struct clk_hw *hw)
1823{
1824 struct clk_tegra *c = to_clk_tegra(hw);
1825
1826 c->state = ON;
1827 if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
1828 c->state = OFF;
1829 if (!(c->flags & PERIPH_NO_RESET))
1830 if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c))
1831 c->state = OFF;
1832 return c->state;
1833}
1834
1835static int tegra30_periph_clk_enable(struct clk_hw *hw)
1836{
1837 struct clk_tegra *c = to_clk_tegra(hw);
1838
1839 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
1840 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
1841 return 0;
1842
1843 clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_SET_REG(c));
1844 if (!(c->flags & PERIPH_NO_RESET) &&
1845 !(c->flags & PERIPH_MANUAL_RESET)) {
1846 if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) &
1847 PERIPH_CLK_TO_BIT(c)) {
1848 udelay(5); /* reset propagation delay */
1849 clk_writel(PERIPH_CLK_TO_BIT(c),
1850 PERIPH_CLK_TO_RST_CLR_REG(c));
1851 }
1852 }
1853 return 0;
1854}
1855
1856static void tegra30_periph_clk_disable(struct clk_hw *hw)
1857{
1858 struct clk_tegra *c = to_clk_tegra(hw);
1859 unsigned long val;
1860
1861 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
1862
1863 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0)
1864 return;
1865
1866 /* If peripheral is in the APB bus then read the APB bus to
1867 * flush the write operation in apb bus. This will avoid the
1868 * peripheral access after disabling clock*/
1869 if (c->flags & PERIPH_ON_APB)
1870 val = chipid_readl();
1871
1872 clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c));
1873}
1874
1875void tegra30_periph_clk_reset(struct clk_hw *hw, bool assert)
1876{
1877 struct clk_tegra *c = to_clk_tegra(hw);
1878 unsigned long val;
1879
1880 if (!(c->flags & PERIPH_NO_RESET)) {
1881 if (assert) {
1882 /* If peripheral is in the APB bus then read the APB
1883 * bus to flush the write operation in apb bus. This
1884 * will avoid the peripheral access after disabling
1885 * clock */
1886 if (c->flags & PERIPH_ON_APB)
1887 val = chipid_readl();
1888
1889 clk_writel(PERIPH_CLK_TO_BIT(c),
1890 PERIPH_CLK_TO_RST_SET_REG(c));
1891 } else
1892 clk_writel(PERIPH_CLK_TO_BIT(c),
1893 PERIPH_CLK_TO_RST_CLR_REG(c));
1894 }
1895}
1896
1897static int tegra30_periph_clk_set_parent(struct clk_hw *hw, u8 index)
1898{
1899 struct clk_tegra *c = to_clk_tegra(hw);
1900 u32 val;
1901
1902 if (!(c->flags & MUX))
1903 return (index == 0) ? 0 : (-EINVAL);
1904
1905 val = clk_readl(c->reg);
1906 val &= ~periph_clk_source_mask(c);
1907 val |= (index << periph_clk_source_shift(c));
1908 clk_writel_delay(val, c->reg);
1909 return 0;
1910}
1911
1912static u8 tegra30_periph_clk_get_parent(struct clk_hw *hw)
1913{
1914 struct clk_tegra *c = to_clk_tegra(hw);
1915 u32 val = clk_readl(c->reg);
1916 int source = (val & periph_clk_source_mask(c)) >>
1917 periph_clk_source_shift(c);
1918
1919 if (!(c->flags & MUX))
1920 return 0;
1921
1922 return source;
1923}
1924
1925static int tegra30_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1926 unsigned long parent_rate)
1927{
1928 struct clk_tegra *c = to_clk_tegra(hw);
1929 u32 val;
1930 int divider;
1931
1932 if (c->flags & DIV_U71) {
1933 divider = clk_div71_get_divider(
1934 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1935 if (divider >= 0) {
1936 val = clk_readl(c->reg);
1937 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
1938 val |= divider;
1939 if (c->flags & DIV_U71_UART) {
1940 if (divider)
1941 val |= PERIPH_CLK_UART_DIV_ENB;
1942 else
1943 val &= ~PERIPH_CLK_UART_DIV_ENB;
1944 }
1945 clk_writel_delay(val, c->reg);
1946 c->div = divider + 2;
1947 c->mul = 2;
1948 return 0;
1949 }
1950 } else if (c->flags & DIV_U16) {
1951 divider = clk_div16_get_divider(parent_rate, rate);
1952 if (divider >= 0) {
1953 val = clk_readl(c->reg);
1954 val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
1955 val |= divider;
1956 clk_writel_delay(val, c->reg);
1957 c->div = divider + 1;
1958 c->mul = 1;
1959 return 0;
1960 }
1961 } else if (parent_rate <= rate) {
1962 c->div = 1;
1963 c->mul = 1;
1964 return 0;
1965 }
1966 return -EINVAL;
1967}
1968
1969static long tegra30_periph_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1970 unsigned long *prate)
1971{
1972 struct clk_tegra *c = to_clk_tegra(hw);
1973 unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
1974 int divider;
1975
1976 if (prate)
1977 parent_rate = *prate;
1978
1979 if (c->flags & DIV_U71) {
1980 divider = clk_div71_get_divider(
1981 parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
1982 if (divider < 0)
1983 return divider;
1984
1985 return DIV_ROUND_UP(parent_rate * 2, divider + 2);
1986 } else if (c->flags & DIV_U16) {
1987 divider = clk_div16_get_divider(parent_rate, rate);
1988 if (divider < 0)
1989 return divider;
1990 return DIV_ROUND_UP(parent_rate, divider + 1);
1991 }
1992 return -EINVAL;
1993}
1994
1995static unsigned long tegra30_periph_clk_recalc_rate(struct clk_hw *hw,
1996 unsigned long parent_rate)
1997{
1998 struct clk_tegra *c = to_clk_tegra(hw);
1999 u64 rate = parent_rate;
2000 u32 val = clk_readl(c->reg);
2001
2002 if (c->flags & DIV_U71) {
2003 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
2004 if ((c->flags & DIV_U71_UART) &&
2005 (!(val & PERIPH_CLK_UART_DIV_ENB))) {
2006 divu71 = 0;
2007 }
2008 if (c->flags & DIV_U71_IDLE) {
2009 val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK <<
2010 PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
2011 val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL <<
2012 PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
2013 clk_writel(val, c->reg);
2014 }
2015 c->div = divu71 + 2;
2016 c->mul = 2;
2017 } else if (c->flags & DIV_U16) {
2018 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
2019 c->div = divu16 + 1;
2020 c->mul = 1;
2021 } else {
2022 c->div = 1;
2023 c->mul = 1;
2024 }
2025
2026 if (c->mul != 0 && c->div != 0) {
2027 rate *= c->mul;
2028 rate += c->div - 1; /* round up */
2029 do_div(rate, c->div);
2030 }
2031 return rate;
2032}
2033
2034struct clk_ops tegra30_periph_clk_ops = {
2035 .is_enabled = tegra30_periph_clk_is_enabled,
2036 .enable = tegra30_periph_clk_enable,
2037 .disable = tegra30_periph_clk_disable,
2038 .set_parent = tegra30_periph_clk_set_parent,
2039 .get_parent = tegra30_periph_clk_get_parent,
2040 .set_rate = tegra30_periph_clk_set_rate,
2041 .round_rate = tegra30_periph_clk_round_rate,
2042 .recalc_rate = tegra30_periph_clk_recalc_rate,
2043};
2044
2045static int tegra30_dsib_clk_set_parent(struct clk_hw *hw, u8 index)
2046{
2047 struct clk *d = clk_get_sys(NULL, "pll_d");
2048 /* The DSIB parent selection bit is in PLLD base register */
2049 tegra_clk_cfg_ex(
2050 d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, index);
2051
2052 return 0;
2053}
2054
2055struct clk_ops tegra30_dsib_clk_ops = {
2056 .is_enabled = tegra30_periph_clk_is_enabled,
2057 .enable = &tegra30_periph_clk_enable,
2058 .disable = &tegra30_periph_clk_disable,
2059 .set_parent = &tegra30_dsib_clk_set_parent,
2060 .get_parent = &tegra30_periph_clk_get_parent,
2061 .set_rate = &tegra30_periph_clk_set_rate,
2062 .round_rate = &tegra30_periph_clk_round_rate,
2063 .recalc_rate = &tegra30_periph_clk_recalc_rate,
2064};
2065
2066/* Periph extended clock configuration ops */
2067int tegra30_vi_clk_cfg_ex(struct clk_hw *hw,
2068 enum tegra_clk_ex_param p, u32 setting)
2069{
2070 struct clk_tegra *c = to_clk_tegra(hw);
2071
2072 if (p == TEGRA_CLK_VI_INP_SEL) {
2073 u32 val = clk_readl(c->reg);
2074 val &= ~PERIPH_CLK_VI_SEL_EX_MASK;
2075 val |= (setting << PERIPH_CLK_VI_SEL_EX_SHIFT) &
2076 PERIPH_CLK_VI_SEL_EX_MASK;
2077 clk_writel(val, c->reg);
2078 return 0;
2079 }
2080 return -EINVAL;
2081}
2082
2083int tegra30_nand_clk_cfg_ex(struct clk_hw *hw,
2084 enum tegra_clk_ex_param p, u32 setting)
2085{
2086 struct clk_tegra *c = to_clk_tegra(hw);
2087
2088 if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) {
2089 u32 val = clk_readl(c->reg);
2090 if (setting)
2091 val |= PERIPH_CLK_NAND_DIV_EX_ENB;
2092 else
2093 val &= ~PERIPH_CLK_NAND_DIV_EX_ENB;
2094 clk_writel(val, c->reg);
2095 return 0;
2096 }
2097 return -EINVAL;
2098}
2099
2100int tegra30_dtv_clk_cfg_ex(struct clk_hw *hw,
2101 enum tegra_clk_ex_param p, u32 setting)
2102{
2103 struct clk_tegra *c = to_clk_tegra(hw);
2104
2105 if (p == TEGRA_CLK_DTV_INVERT) {
2106 u32 val = clk_readl(c->reg);
2107 if (setting)
2108 val |= PERIPH_CLK_DTV_POLARITY_INV;
2109 else
2110 val &= ~PERIPH_CLK_DTV_POLARITY_INV;
2111 clk_writel(val, c->reg);
2112 return 0;
2113 }
2114 return -EINVAL;
2115}
2116
2117/* Output clock ops */
2118
2119static DEFINE_SPINLOCK(clk_out_lock);
2120
2121static int tegra30_clk_out_is_enabled(struct clk_hw *hw)
2122{
2123 struct clk_tegra *c = to_clk_tegra(hw);
2124 u32 val = pmc_readl(c->reg);
2125
2126 c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF;
2127 c->mul = 1;
2128 c->div = 1;
2129 return c->state;
2130}
2131
2132static int tegra30_clk_out_enable(struct clk_hw *hw)
2133{
2134 struct clk_tegra *c = to_clk_tegra(hw);
2135 u32 val;
2136 unsigned long flags;
2137
2138 spin_lock_irqsave(&clk_out_lock, flags);
2139 val = pmc_readl(c->reg);
2140 val |= (0x1 << c->u.periph.clk_num);
2141 pmc_writel(val, c->reg);
2142 spin_unlock_irqrestore(&clk_out_lock, flags);
2143
2144 return 0;
2145}
2146
2147static void tegra30_clk_out_disable(struct clk_hw *hw)
2148{
2149 struct clk_tegra *c = to_clk_tegra(hw);
2150 u32 val;
2151 unsigned long flags;
2152
2153 spin_lock_irqsave(&clk_out_lock, flags);
2154 val = pmc_readl(c->reg);
2155 val &= ~(0x1 << c->u.periph.clk_num);
2156 pmc_writel(val, c->reg);
2157 spin_unlock_irqrestore(&clk_out_lock, flags);
2158}
2159
2160static int tegra30_clk_out_set_parent(struct clk_hw *hw, u8 index)
2161{
2162 struct clk_tegra *c = to_clk_tegra(hw);
2163 u32 val;
2164 unsigned long flags;
2165
2166 spin_lock_irqsave(&clk_out_lock, flags);
2167 val = pmc_readl(c->reg);
2168 val &= ~periph_clk_source_mask(c);
2169 val |= (index << periph_clk_source_shift(c));
2170 pmc_writel(val, c->reg);
2171 spin_unlock_irqrestore(&clk_out_lock, flags);
2172
2173 return 0;
2174}
2175
2176static u8 tegra30_clk_out_get_parent(struct clk_hw *hw)
2177{
2178 struct clk_tegra *c = to_clk_tegra(hw);
2179 u32 val = pmc_readl(c->reg);
2180 int source;
2181
2182 source = (val & periph_clk_source_mask(c)) >>
2183 periph_clk_source_shift(c);
2184 return source;
2185}
2186
2187struct clk_ops tegra_clk_out_ops = {
2188 .is_enabled = tegra30_clk_out_is_enabled,
2189 .enable = tegra30_clk_out_enable,
2190 .disable = tegra30_clk_out_disable,
2191 .set_parent = tegra30_clk_out_set_parent,
2192 .get_parent = tegra30_clk_out_get_parent,
2193 .recalc_rate = tegra30_clk_fixed_recalc_rate,
2194};
2195
2196/* Clock doubler ops */
2197static int tegra30_clk_double_is_enabled(struct clk_hw *hw)
2198{
2199 struct clk_tegra *c = to_clk_tegra(hw);
2200
2201 c->state = ON;
2202 if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
2203 c->state = OFF;
2204 return c->state;
2205};
2206
2207static int tegra30_clk_double_set_rate(struct clk_hw *hw, unsigned long rate,
2208 unsigned long parent_rate)
2209{
2210 struct clk_tegra *c = to_clk_tegra(hw);
2211 u32 val;
2212
2213 if (rate == parent_rate) {
2214 val = clk_readl(c->reg) | (0x1 << c->reg_shift);
2215 clk_writel(val, c->reg);
2216 c->mul = 1;
2217 c->div = 1;
2218 return 0;
2219 } else if (rate == 2 * parent_rate) {
2220 val = clk_readl(c->reg) & (~(0x1 << c->reg_shift));
2221 clk_writel(val, c->reg);
2222 c->mul = 2;
2223 c->div = 1;
2224 return 0;
2225 }
2226 return -EINVAL;
2227}
2228
2229static unsigned long tegra30_clk_double_recalc_rate(struct clk_hw *hw,
2230 unsigned long parent_rate)
2231{
2232 struct clk_tegra *c = to_clk_tegra(hw);
2233 u64 rate = parent_rate;
2234
2235 u32 val = clk_readl(c->reg);
2236 c->mul = val & (0x1 << c->reg_shift) ? 1 : 2;
2237 c->div = 1;
2238
2239 if (c->mul != 0 && c->div != 0) {
2240 rate *= c->mul;
2241 rate += c->div - 1; /* round up */
2242 do_div(rate, c->div);
2243 }
2244
2245 return rate;
2246}
2247
2248static long tegra30_clk_double_round_rate(struct clk_hw *hw, unsigned long rate,
2249 unsigned long *prate)
2250{
2251 unsigned long output_rate = *prate;
2252
2253 do_div(output_rate, 2);
2254 return output_rate;
2255}
2256
2257struct clk_ops tegra30_clk_double_ops = {
2258 .is_enabled = tegra30_clk_double_is_enabled,
2259 .enable = tegra30_periph_clk_enable,
2260 .disable = tegra30_periph_clk_disable,
2261 .recalc_rate = tegra30_clk_double_recalc_rate,
2262 .round_rate = tegra30_clk_double_round_rate,
2263 .set_rate = tegra30_clk_double_set_rate,
2264};
2265
2266/* Audio sync clock ops */
2267struct clk_ops tegra_sync_source_ops = {
2268 .recalc_rate = tegra30_clk_fixed_recalc_rate,
2269};
2270
2271static int tegra30_audio_sync_clk_is_enabled(struct clk_hw *hw)
2272{
2273 struct clk_tegra *c = to_clk_tegra(hw);
2274 u32 val = clk_readl(c->reg);
2275 c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON;
2276 return c->state;
2277}
2278
2279static int tegra30_audio_sync_clk_enable(struct clk_hw *hw)
2280{
2281 struct clk_tegra *c = to_clk_tegra(hw);
2282 u32 val = clk_readl(c->reg);
2283 clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg);
2284 return 0;
2285}
2286
2287static void tegra30_audio_sync_clk_disable(struct clk_hw *hw)
2288{
2289 struct clk_tegra *c = to_clk_tegra(hw);
2290 u32 val = clk_readl(c->reg);
2291 clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg);
2292}
2293
2294static int tegra30_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index)
2295{
2296 struct clk_tegra *c = to_clk_tegra(hw);
2297 u32 val;
2298
2299 val = clk_readl(c->reg);
2300 val &= ~AUDIO_SYNC_SOURCE_MASK;
2301 val |= index;
2302
2303 clk_writel(val, c->reg);
2304 return 0;
2305}
2306
2307static u8 tegra30_audio_sync_clk_get_parent(struct clk_hw *hw)
2308{
2309 struct clk_tegra *c = to_clk_tegra(hw);
2310 u32 val = clk_readl(c->reg);
2311 int source;
2312
2313 source = val & AUDIO_SYNC_SOURCE_MASK;
2314 return source;
2315}
2316
2317struct clk_ops tegra30_audio_sync_clk_ops = {
2318 .is_enabled = tegra30_audio_sync_clk_is_enabled,
2319 .enable = tegra30_audio_sync_clk_enable,
2320 .disable = tegra30_audio_sync_clk_disable,
2321 .set_parent = tegra30_audio_sync_clk_set_parent,
2322 .get_parent = tegra30_audio_sync_clk_get_parent,
2323 .recalc_rate = tegra30_clk_fixed_recalc_rate,
2324};
2325
2326/* cml0 (pcie), and cml1 (sata) clock ops */
2327static int tegra30_cml_clk_is_enabled(struct clk_hw *hw)
2328{
2329 struct clk_tegra *c = to_clk_tegra(hw);
2330 u32 val = clk_readl(c->reg);
2331 c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF;
2332 return c->state;
2333}
2334
2335static int tegra30_cml_clk_enable(struct clk_hw *hw)
2336{
2337 struct clk_tegra *c = to_clk_tegra(hw);
2338
2339 u32 val = clk_readl(c->reg);
2340 val |= (0x1 << c->u.periph.clk_num);
2341 clk_writel(val, c->reg);
2342
2343 return 0;
2344}
2345
2346static void tegra30_cml_clk_disable(struct clk_hw *hw)
2347{
2348 struct clk_tegra *c = to_clk_tegra(hw);
2349
2350 u32 val = clk_readl(c->reg);
2351 val &= ~(0x1 << c->u.periph.clk_num);
2352 clk_writel(val, c->reg);
2353}
2354
2355struct clk_ops tegra_cml_clk_ops = {
2356 .is_enabled = tegra30_cml_clk_is_enabled,
2357 .enable = tegra30_cml_clk_enable,
2358 .disable = tegra30_cml_clk_disable,
2359 .recalc_rate = tegra30_clk_fixed_recalc_rate,
2360};
2361
2362struct clk_ops tegra_pciex_clk_ops = {
2363 .recalc_rate = tegra30_clk_fixed_recalc_rate,
2364};
2365
2366/* Tegra30 CPU clock and reset control functions */
2367static void tegra30_wait_cpu_in_reset(u32 cpu)
2368{
2369 unsigned int reg;
2370
2371 do {
2372 reg = readl(reg_clk_base +
2373 TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
2374 cpu_relax();
2375 } while (!(reg & (1 << cpu))); /* check CPU been reset or not */
2376
2377 return;
2378}
2379
2380static void tegra30_put_cpu_in_reset(u32 cpu)
2381{
2382 writel(CPU_RESET(cpu),
2383 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
2384 dmb();
2385}
2386
2387static void tegra30_cpu_out_of_reset(u32 cpu)
2388{
2389 writel(CPU_RESET(cpu),
2390 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
2391 wmb();
2392}
2393
2394static void tegra30_enable_cpu_clock(u32 cpu)
2395{
2396 unsigned int reg;
2397
2398 writel(CPU_CLOCK(cpu),
2399 reg_clk_base + TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR);
2400 reg = readl(reg_clk_base +
2401 TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR);
2402}
2403
2404static void tegra30_disable_cpu_clock(u32 cpu)
2405{
2406
2407 unsigned int reg;
2408
2409 reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
2410 writel(reg | CPU_CLOCK(cpu),
2411 reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
2412}
2413
2414#ifdef CONFIG_PM_SLEEP
2415static bool tegra30_cpu_rail_off_ready(void)
2416{
2417 unsigned int cpu_rst_status;
2418 int cpu_pwr_status;
2419
2420 cpu_rst_status = readl(reg_clk_base +
2421 TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
2422 cpu_pwr_status = tegra_powergate_is_powered(TEGRA_POWERGATE_CPU1) ||
2423 tegra_powergate_is_powered(TEGRA_POWERGATE_CPU2) ||
2424 tegra_powergate_is_powered(TEGRA_POWERGATE_CPU3);
2425
2426 if (((cpu_rst_status & 0xE) != 0xE) || cpu_pwr_status)
2427 return false;
2428
2429 return true;
2430}
2431
2432static void tegra30_cpu_clock_suspend(void)
2433{
2434 /* switch coresite to clk_m, save off original source */
2435 tegra30_cpu_clk_sctx.clk_csite_src =
2436 readl(reg_clk_base + CLK_RESET_SOURCE_CSITE);
2437 writel(3<<30, reg_clk_base + CLK_RESET_SOURCE_CSITE);
2438
2439 tegra30_cpu_clk_sctx.cpu_burst =
2440 readl(reg_clk_base + CLK_RESET_CCLK_BURST);
2441 tegra30_cpu_clk_sctx.pllx_base =
2442 readl(reg_clk_base + CLK_RESET_PLLX_BASE);
2443 tegra30_cpu_clk_sctx.pllx_misc =
2444 readl(reg_clk_base + CLK_RESET_PLLX_MISC);
2445 tegra30_cpu_clk_sctx.cclk_divider =
2446 readl(reg_clk_base + CLK_RESET_CCLK_DIVIDER);
2447}
2448
2449static void tegra30_cpu_clock_resume(void)
2450{
2451 unsigned int reg, policy;
2452
2453 /* Is CPU complex already running on PLLX? */
2454 reg = readl(reg_clk_base + CLK_RESET_CCLK_BURST);
2455 policy = (reg >> CLK_RESET_CCLK_BURST_POLICY_SHIFT) & 0xF;
2456
2457 if (policy == CLK_RESET_CCLK_IDLE_POLICY)
2458 reg = (reg >> CLK_RESET_CCLK_IDLE_POLICY_SHIFT) & 0xF;
2459 else if (policy == CLK_RESET_CCLK_RUN_POLICY)
2460 reg = (reg >> CLK_RESET_CCLK_RUN_POLICY_SHIFT) & 0xF;
2461 else
2462 BUG();
2463
2464 if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) {
2465 /* restore PLLX settings if CPU is on different PLL */
2466 writel(tegra30_cpu_clk_sctx.pllx_misc,
2467 reg_clk_base + CLK_RESET_PLLX_MISC);
2468 writel(tegra30_cpu_clk_sctx.pllx_base,
2469 reg_clk_base + CLK_RESET_PLLX_BASE);
2470
2471 /* wait for PLL stabilization if PLLX was enabled */
2472 if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30))
2473 udelay(300);
2474 }
2475
2476 /*
2477 * Restore original burst policy setting for calls resulting from CPU
2478 * LP2 in idle or system suspend.
2479 */
2480 writel(tegra30_cpu_clk_sctx.cclk_divider,
2481 reg_clk_base + CLK_RESET_CCLK_DIVIDER);
2482 writel(tegra30_cpu_clk_sctx.cpu_burst,
2483 reg_clk_base + CLK_RESET_CCLK_BURST);
2484
2485 writel(tegra30_cpu_clk_sctx.clk_csite_src,
2486 reg_clk_base + CLK_RESET_SOURCE_CSITE);
2487}
2488#endif
2489
2490static struct tegra_cpu_car_ops tegra30_cpu_car_ops = {
2491 .wait_for_reset = tegra30_wait_cpu_in_reset,
2492 .put_in_reset = tegra30_put_cpu_in_reset,
2493 .out_of_reset = tegra30_cpu_out_of_reset,
2494 .enable_clock = tegra30_enable_cpu_clock,
2495 .disable_clock = tegra30_disable_cpu_clock,
2496#ifdef CONFIG_PM_SLEEP
2497 .rail_off_ready = tegra30_cpu_rail_off_ready,
2498 .suspend = tegra30_cpu_clock_suspend,
2499 .resume = tegra30_cpu_clock_resume,
2500#endif
2501};
2502
2503void __init tegra30_cpu_car_ops_init(void)
2504{
2505 tegra_cpu_car_ops = &tegra30_cpu_car_ops;
2506}
diff --git a/arch/arm/mach-tegra/tegra30_clocks.h b/arch/arm/mach-tegra/tegra30_clocks.h
deleted file mode 100644
index 7a34adb2f72d..000000000000
--- a/arch/arm/mach-tegra/tegra30_clocks.h
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __MACH_TEGRA30_CLOCK_H
18#define __MACH_TEGRA30_CLOCK_H
19
20extern struct clk_ops tegra30_clk_32k_ops;
21extern struct clk_ops tegra30_clk_m_ops;
22extern struct clk_ops tegra_clk_m_div_ops;
23extern struct clk_ops tegra_pll_ref_ops;
24extern struct clk_ops tegra30_pll_ops;
25extern struct clk_ops tegra30_pll_div_ops;
26extern struct clk_ops tegra_plld_ops;
27extern struct clk_ops tegra30_plle_ops;
28extern struct clk_ops tegra_cml_clk_ops;
29extern struct clk_ops tegra_pciex_clk_ops;
30extern struct clk_ops tegra_sync_source_ops;
31extern struct clk_ops tegra30_audio_sync_clk_ops;
32extern struct clk_ops tegra30_clk_double_ops;
33extern struct clk_ops tegra_clk_out_ops;
34extern struct clk_ops tegra30_super_ops;
35extern struct clk_ops tegra30_blink_clk_ops;
36extern struct clk_ops tegra30_twd_ops;
37extern struct clk_ops tegra30_bus_ops;
38extern struct clk_ops tegra30_periph_clk_ops;
39extern struct clk_ops tegra30_dsib_clk_ops;
40extern struct clk_ops tegra_nand_clk_ops;
41extern struct clk_ops tegra_vi_clk_ops;
42extern struct clk_ops tegra_dtv_clk_ops;
43extern struct clk_ops tegra_clk_shared_bus_ops;
44
45int tegra30_plld_clk_cfg_ex(struct clk_hw *hw,
46 enum tegra_clk_ex_param p, u32 setting);
47void tegra30_periph_clk_reset(struct clk_hw *hw, bool assert);
48int tegra30_vi_clk_cfg_ex(struct clk_hw *hw,
49 enum tegra_clk_ex_param p, u32 setting);
50int tegra30_nand_clk_cfg_ex(struct clk_hw *hw,
51 enum tegra_clk_ex_param p, u32 setting);
52int tegra30_dtv_clk_cfg_ex(struct clk_hw *hw,
53 enum tegra_clk_ex_param p, u32 setting);
54#endif
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c b/arch/arm/mach-tegra/tegra30_clocks_data.c
deleted file mode 100644
index 741d264d5ecb..000000000000
--- a/arch/arm/mach-tegra/tegra30_clocks_data.c
+++ /dev/null
@@ -1,1425 +0,0 @@
1/*
2 * arch/arm/mach-tegra/tegra30_clocks.c
3 *
4 * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20
21#include <linux/clk-private.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/list.h>
25#include <linux/spinlock.h>
26#include <linux/delay.h>
27#include <linux/err.h>
28#include <linux/io.h>
29#include <linux/clk.h>
30#include <linux/cpufreq.h>
31
32#include "clock.h"
33#include "fuse.h"
34#include "tegra30_clocks.h"
35#include "tegra_cpu_car.h"
36
37#define DEFINE_CLK_TEGRA(_name, _rate, _ops, _flags, \
38 _parent_names, _parents, _parent) \
39 static struct clk tegra_##_name = { \
40 .hw = &tegra_##_name##_hw.hw, \
41 .name = #_name, \
42 .rate = _rate, \
43 .ops = _ops, \
44 .flags = _flags, \
45 .parent_names = _parent_names, \
46 .parents = _parents, \
47 .num_parents = ARRAY_SIZE(_parent_names), \
48 .parent = _parent, \
49 };
50
51static struct clk tegra_clk_32k;
52static struct clk_tegra tegra_clk_32k_hw = {
53 .hw = {
54 .clk = &tegra_clk_32k,
55 },
56 .fixed_rate = 32768,
57};
58static struct clk tegra_clk_32k = {
59 .name = "clk_32k",
60 .hw = &tegra_clk_32k_hw.hw,
61 .ops = &tegra30_clk_32k_ops,
62 .flags = CLK_IS_ROOT,
63};
64
65static struct clk tegra_clk_m;
66static struct clk_tegra tegra_clk_m_hw = {
67 .hw = {
68 .clk = &tegra_clk_m,
69 },
70 .flags = ENABLE_ON_INIT,
71 .reg = 0x1fc,
72 .reg_shift = 28,
73 .max_rate = 48000000,
74};
75static struct clk tegra_clk_m = {
76 .name = "clk_m",
77 .hw = &tegra_clk_m_hw.hw,
78 .ops = &tegra30_clk_m_ops,
79 .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
80};
81
82static const char *clk_m_div_parent_names[] = {
83 "clk_m",
84};
85
86static struct clk *clk_m_div_parents[] = {
87 &tegra_clk_m,
88};
89
90static struct clk tegra_clk_m_div2;
91static struct clk_tegra tegra_clk_m_div2_hw = {
92 .hw = {
93 .clk = &tegra_clk_m_div2,
94 },
95 .mul = 1,
96 .div = 2,
97 .max_rate = 24000000,
98};
99DEFINE_CLK_TEGRA(clk_m_div2, 0, &tegra_clk_m_div_ops, 0,
100 clk_m_div_parent_names, clk_m_div_parents, &tegra_clk_m);
101
102static struct clk tegra_clk_m_div4;
103static struct clk_tegra tegra_clk_m_div4_hw = {
104 .hw = {
105 .clk = &tegra_clk_m_div4,
106 },
107 .mul = 1,
108 .div = 4,
109 .max_rate = 12000000,
110};
111DEFINE_CLK_TEGRA(clk_m_div4, 0, &tegra_clk_m_div_ops, 0,
112 clk_m_div_parent_names, clk_m_div_parents, &tegra_clk_m);
113
114static struct clk tegra_pll_ref;
115static struct clk_tegra tegra_pll_ref_hw = {
116 .hw = {
117 .clk = &tegra_pll_ref,
118 },
119 .flags = ENABLE_ON_INIT,
120 .max_rate = 26000000,
121};
122DEFINE_CLK_TEGRA(pll_ref, 0, &tegra_pll_ref_ops, 0, clk_m_div_parent_names,
123 clk_m_div_parents, &tegra_clk_m);
124
125#define DEFINE_PLL(_name, _flags, _reg, _max_rate, _input_min, \
126 _input_max, _cf_min, _cf_max, _vco_min, \
127 _vco_max, _freq_table, _lock_delay, _ops, \
128 _fixed_rate, _clk_cfg_ex, _parent) \
129 static struct clk tegra_##_name; \
130 static const char *_name##_parent_names[] = { \
131 #_parent, \
132 }; \
133 static struct clk *_name##_parents[] = { \
134 &tegra_##_parent, \
135 }; \
136 static struct clk_tegra tegra_##_name##_hw = { \
137 .hw = { \
138 .clk = &tegra_##_name, \
139 }, \
140 .flags = _flags, \
141 .reg = _reg, \
142 .max_rate = _max_rate, \
143 .u.pll = { \
144 .input_min = _input_min, \
145 .input_max = _input_max, \
146 .cf_min = _cf_min, \
147 .cf_max = _cf_max, \
148 .vco_min = _vco_min, \
149 .vco_max = _vco_max, \
150 .freq_table = _freq_table, \
151 .lock_delay = _lock_delay, \
152 .fixed_rate = _fixed_rate, \
153 }, \
154 .clk_cfg_ex = _clk_cfg_ex, \
155 }; \
156 DEFINE_CLK_TEGRA(_name, 0, &_ops, CLK_IGNORE_UNUSED, \
157 _name##_parent_names, _name##_parents, \
158 &tegra_##_parent);
159
160#define DEFINE_PLL_OUT(_name, _flags, _reg, _reg_shift, \
161 _max_rate, _ops, _parent, _clk_flags) \
162 static const char *_name##_parent_names[] = { \
163 #_parent, \
164 }; \
165 static struct clk *_name##_parents[] = { \
166 &tegra_##_parent, \
167 }; \
168 static struct clk tegra_##_name; \
169 static struct clk_tegra tegra_##_name##_hw = { \
170 .hw = { \
171 .clk = &tegra_##_name, \
172 }, \
173 .flags = _flags, \
174 .reg = _reg, \
175 .max_rate = _max_rate, \
176 .reg_shift = _reg_shift, \
177 }; \
178 DEFINE_CLK_TEGRA(_name, 0, &tegra30_pll_div_ops, \
179 _clk_flags, _name##_parent_names, \
180 _name##_parents, &tegra_##_parent);
181
182static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
183 { 12000000, 1040000000, 520, 6, 1, 8},
184 { 13000000, 1040000000, 480, 6, 1, 8},
185 { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */
186 { 19200000, 1040000000, 325, 6, 1, 6},
187 { 26000000, 1040000000, 520, 13, 1, 8},
188
189 { 12000000, 832000000, 416, 6, 1, 8},
190 { 13000000, 832000000, 832, 13, 1, 8},
191 { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */
192 { 19200000, 832000000, 260, 6, 1, 8},
193 { 26000000, 832000000, 416, 13, 1, 8},
194
195 { 12000000, 624000000, 624, 12, 1, 8},
196 { 13000000, 624000000, 624, 13, 1, 8},
197 { 16800000, 600000000, 520, 14, 1, 8},
198 { 19200000, 624000000, 520, 16, 1, 8},
199 { 26000000, 624000000, 624, 26, 1, 8},
200
201 { 12000000, 600000000, 600, 12, 1, 8},
202 { 13000000, 600000000, 600, 13, 1, 8},
203 { 16800000, 600000000, 500, 14, 1, 8},
204 { 19200000, 600000000, 375, 12, 1, 6},
205 { 26000000, 600000000, 600, 26, 1, 8},
206
207 { 12000000, 520000000, 520, 12, 1, 8},
208 { 13000000, 520000000, 520, 13, 1, 8},
209 { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */
210 { 19200000, 520000000, 325, 12, 1, 6},
211 { 26000000, 520000000, 520, 26, 1, 8},
212
213 { 12000000, 416000000, 416, 12, 1, 8},
214 { 13000000, 416000000, 416, 13, 1, 8},
215 { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */
216 { 19200000, 416000000, 260, 12, 1, 6},
217 { 26000000, 416000000, 416, 26, 1, 8},
218 { 0, 0, 0, 0, 0, 0 },
219};
220
221DEFINE_PLL(pll_c, PLL_HAS_CPCON, 0x80, 1400000000, 2000000, 31000000, 1000000,
222 6000000, 20000000, 1400000000, tegra_pll_c_freq_table, 300,
223 tegra30_pll_ops, 0, NULL, pll_ref);
224
225DEFINE_PLL_OUT(pll_c_out1, DIV_U71, 0x84, 0, 700000000,
226 tegra30_pll_div_ops, pll_c, CLK_IGNORE_UNUSED);
227
228static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
229 { 12000000, 666000000, 666, 12, 1, 8},
230 { 13000000, 666000000, 666, 13, 1, 8},
231 { 16800000, 666000000, 555, 14, 1, 8},
232 { 19200000, 666000000, 555, 16, 1, 8},
233 { 26000000, 666000000, 666, 26, 1, 8},
234 { 12000000, 600000000, 600, 12, 1, 8},
235 { 13000000, 600000000, 600, 13, 1, 8},
236 { 16800000, 600000000, 500, 14, 1, 8},
237 { 19200000, 600000000, 375, 12, 1, 6},
238 { 26000000, 600000000, 600, 26, 1, 8},
239 { 0, 0, 0, 0, 0, 0 },
240};
241
242DEFINE_PLL(pll_m, PLL_HAS_CPCON | PLLM, 0x90, 800000000, 2000000, 31000000,
243 1000000, 6000000, 20000000, 1200000000, tegra_pll_m_freq_table,
244 300, tegra30_pll_ops, 0, NULL, pll_ref);
245
246DEFINE_PLL_OUT(pll_m_out1, DIV_U71, 0x94, 0, 600000000,
247 tegra30_pll_div_ops, pll_m, CLK_IGNORE_UNUSED);
248
249static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
250 { 12000000, 216000000, 432, 12, 2, 8},
251 { 13000000, 216000000, 432, 13, 2, 8},
252 { 16800000, 216000000, 360, 14, 2, 8},
253 { 19200000, 216000000, 360, 16, 2, 8},
254 { 26000000, 216000000, 432, 26, 2, 8},
255 { 0, 0, 0, 0, 0, 0 },
256};
257
258DEFINE_PLL(pll_p, ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, 0xa0, 432000000,
259 2000000, 31000000, 1000000, 6000000, 20000000, 1400000000,
260 tegra_pll_p_freq_table, 300, tegra30_pll_ops, 408000000, NULL,
261 pll_ref);
262
263DEFINE_PLL_OUT(pll_p_out1, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4,
264 0, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED);
265DEFINE_PLL_OUT(pll_p_out2, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4,
266 16, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED);
267DEFINE_PLL_OUT(pll_p_out3, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8,
268 0, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED);
269DEFINE_PLL_OUT(pll_p_out4, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8,
270 16, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED);
271
272static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
273 { 9600000, 564480000, 294, 5, 1, 4},
274 { 9600000, 552960000, 288, 5, 1, 4},
275 { 9600000, 24000000, 5, 2, 1, 1},
276
277 { 28800000, 56448000, 49, 25, 1, 1},
278 { 28800000, 73728000, 64, 25, 1, 1},
279 { 28800000, 24000000, 5, 6, 1, 1},
280 { 0, 0, 0, 0, 0, 0 },
281};
282
283DEFINE_PLL(pll_a, PLL_HAS_CPCON, 0xb0, 700000000, 2000000, 31000000, 1000000,
284 6000000, 20000000, 1400000000, tegra_pll_a_freq_table,
285 300, tegra30_pll_ops, 0, NULL, pll_p_out1);
286
287DEFINE_PLL_OUT(pll_a_out0, DIV_U71, 0xb4, 0, 100000000, tegra30_pll_div_ops,
288 pll_a, CLK_IGNORE_UNUSED);
289
290static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
291 { 12000000, 216000000, 216, 12, 1, 4},
292 { 13000000, 216000000, 216, 13, 1, 4},
293 { 16800000, 216000000, 180, 14, 1, 4},
294 { 19200000, 216000000, 180, 16, 1, 4},
295 { 26000000, 216000000, 216, 26, 1, 4},
296
297 { 12000000, 594000000, 594, 12, 1, 8},
298 { 13000000, 594000000, 594, 13, 1, 8},
299 { 16800000, 594000000, 495, 14, 1, 8},
300 { 19200000, 594000000, 495, 16, 1, 8},
301 { 26000000, 594000000, 594, 26, 1, 8},
302
303 { 12000000, 1000000000, 1000, 12, 1, 12},
304 { 13000000, 1000000000, 1000, 13, 1, 12},
305 { 19200000, 1000000000, 625, 12, 1, 8},
306 { 26000000, 1000000000, 1000, 26, 1, 12},
307
308 { 0, 0, 0, 0, 0, 0 },
309};
310
311DEFINE_PLL(pll_d, PLL_HAS_CPCON | PLLD, 0xd0, 1000000000, 2000000, 40000000,
312 1000000, 6000000, 40000000, 1000000000, tegra_pll_d_freq_table,
313 1000, tegra30_pll_ops, 0, tegra30_plld_clk_cfg_ex, pll_ref);
314
315DEFINE_PLL_OUT(pll_d_out0, DIV_2 | PLLD, 0, 0, 500000000, tegra30_pll_div_ops,
316 pll_d, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED);
317
318DEFINE_PLL(pll_d2, PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD, 0x4b8, 1000000000,
319 2000000, 40000000, 1000000, 6000000, 40000000, 1000000000,
320 tegra_pll_d_freq_table, 1000, tegra30_pll_ops, 0, NULL,
321 pll_ref);
322
323DEFINE_PLL_OUT(pll_d2_out0, DIV_2 | PLLD, 0, 0, 500000000, tegra30_pll_div_ops,
324 pll_d2, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED);
325
326static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
327 { 12000000, 480000000, 960, 12, 2, 12},
328 { 13000000, 480000000, 960, 13, 2, 12},
329 { 16800000, 480000000, 400, 7, 2, 5},
330 { 19200000, 480000000, 200, 4, 2, 3},
331 { 26000000, 480000000, 960, 26, 2, 12},
332 { 0, 0, 0, 0, 0, 0 },
333};
334
335DEFINE_PLL(pll_u, PLL_HAS_CPCON | PLLU, 0xc0, 480000000, 2000000, 40000000,
336 1000000, 6000000, 48000000, 960000000, tegra_pll_u_freq_table,
337 1000, tegra30_pll_ops, 0, NULL, pll_ref);
338
339static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
340 /* 1.7 GHz */
341 { 12000000, 1700000000, 850, 6, 1, 8},
342 { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */
343 { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */
344 { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */
345 { 26000000, 1700000000, 850, 13, 1, 8},
346
347 /* 1.6 GHz */
348 { 12000000, 1600000000, 800, 6, 1, 8},
349 { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */
350 { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */
351 { 19200000, 1600000000, 500, 6, 1, 8},
352 { 26000000, 1600000000, 800, 13, 1, 8},
353
354 /* 1.5 GHz */
355 { 12000000, 1500000000, 750, 6, 1, 8},
356 { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */
357 { 16800000, 1500000000, 625, 7, 1, 8},
358 { 19200000, 1500000000, 625, 8, 1, 8},
359 { 26000000, 1500000000, 750, 13, 1, 8},
360
361 /* 1.4 GHz */
362 { 12000000, 1400000000, 700, 6, 1, 8},
363 { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */
364 { 16800000, 1400000000, 1000, 12, 1, 8},
365 { 19200000, 1400000000, 875, 12, 1, 8},
366 { 26000000, 1400000000, 700, 13, 1, 8},
367
368 /* 1.3 GHz */
369 { 12000000, 1300000000, 975, 9, 1, 8},
370 { 13000000, 1300000000, 1000, 10, 1, 8},
371 { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */
372 { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */
373 { 26000000, 1300000000, 650, 13, 1, 8},
374
375 /* 1.2 GHz */
376 { 12000000, 1200000000, 1000, 10, 1, 8},
377 { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */
378 { 16800000, 1200000000, 1000, 14, 1, 8},
379 { 19200000, 1200000000, 1000, 16, 1, 8},
380 { 26000000, 1200000000, 600, 13, 1, 8},
381
382 /* 1.1 GHz */
383 { 12000000, 1100000000, 825, 9, 1, 8},
384 { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */
385 { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */
386 { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */
387 { 26000000, 1100000000, 550, 13, 1, 8},
388
389 /* 1 GHz */
390 { 12000000, 1000000000, 1000, 12, 1, 8},
391 { 13000000, 1000000000, 1000, 13, 1, 8},
392 { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */
393 { 19200000, 1000000000, 625, 12, 1, 8},
394 { 26000000, 1000000000, 1000, 26, 1, 8},
395
396 { 0, 0, 0, 0, 0, 0 },
397};
398
399DEFINE_PLL(pll_x, PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX, 0xe0, 1700000000,
400 2000000, 31000000, 1000000, 6000000, 20000000, 1700000000,
401 tegra_pll_x_freq_table, 300, tegra30_pll_ops, 0, NULL, pll_ref);
402
403DEFINE_PLL_OUT(pll_x_out0, DIV_2 | PLLX, 0, 0, 850000000, tegra30_pll_div_ops,
404 pll_x, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED);
405
406static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
407 /* PLLE special case: use cpcon field to store cml divider value */
408 { 12000000, 100000000, 150, 1, 18, 11},
409 { 216000000, 100000000, 200, 18, 24, 13},
410 { 0, 0, 0, 0, 0, 0 },
411};
412
413DEFINE_PLL(pll_e, PLL_ALT_MISC_REG, 0xe8, 100000000, 2000000, 216000000,
414 12000000, 12000000, 1200000000, 2400000000U,
415 tegra_pll_e_freq_table, 300, tegra30_plle_ops, 100000000, NULL,
416 pll_ref);
417
418static const char *mux_plle[] = {
419 "pll_e",
420};
421
422static struct clk *mux_plle_p[] = {
423 &tegra_pll_e,
424};
425
426static struct clk tegra_cml0;
427static struct clk_tegra tegra_cml0_hw = {
428 .hw = {
429 .clk = &tegra_cml0,
430 },
431 .reg = 0x48c,
432 .fixed_rate = 100000000,
433 .u.periph = {
434 .clk_num = 0,
435 },
436};
437DEFINE_CLK_TEGRA(cml0, 0, &tegra_cml_clk_ops, 0, mux_plle,
438 mux_plle_p, &tegra_pll_e);
439
440static struct clk tegra_cml1;
441static struct clk_tegra tegra_cml1_hw = {
442 .hw = {
443 .clk = &tegra_cml1,
444 },
445 .reg = 0x48c,
446 .fixed_rate = 100000000,
447 .u.periph = {
448 .clk_num = 1,
449 },
450};
451DEFINE_CLK_TEGRA(cml1, 0, &tegra_cml_clk_ops, 0, mux_plle,
452 mux_plle_p, &tegra_pll_e);
453
454static struct clk tegra_pciex;
455static struct clk_tegra tegra_pciex_hw = {
456 .hw = {
457 .clk = &tegra_pciex,
458 },
459 .reg = 0x48c,
460 .fixed_rate = 100000000,
461 .reset = tegra30_periph_clk_reset,
462 .u.periph = {
463 .clk_num = 74,
464 },
465};
466DEFINE_CLK_TEGRA(pciex, 0, &tegra_pciex_clk_ops, 0, mux_plle,
467 mux_plle_p, &tegra_pll_e);
468
469#define SYNC_SOURCE(_name) \
470 static struct clk tegra_##_name##_sync; \
471 static struct clk_tegra tegra_##_name##_sync_hw = { \
472 .hw = { \
473 .clk = &tegra_##_name##_sync, \
474 }, \
475 .max_rate = 24000000, \
476 .fixed_rate = 24000000, \
477 }; \
478 static struct clk tegra_##_name##_sync = { \
479 .name = #_name "_sync", \
480 .hw = &tegra_##_name##_sync_hw.hw, \
481 .ops = &tegra_sync_source_ops, \
482 .flags = CLK_IS_ROOT, \
483 };
484
485SYNC_SOURCE(spdif_in);
486SYNC_SOURCE(i2s0);
487SYNC_SOURCE(i2s1);
488SYNC_SOURCE(i2s2);
489SYNC_SOURCE(i2s3);
490SYNC_SOURCE(i2s4);
491SYNC_SOURCE(vimclk);
492
493static struct clk *tegra_sync_source_list[] = {
494 &tegra_spdif_in_sync,
495 &tegra_i2s0_sync,
496 &tegra_i2s1_sync,
497 &tegra_i2s2_sync,
498 &tegra_i2s3_sync,
499 &tegra_i2s4_sync,
500 &tegra_vimclk_sync,
501};
502
503static const char *mux_audio_sync_clk[] = {
504 "spdif_in_sync",
505 "i2s0_sync",
506 "i2s1_sync",
507 "i2s2_sync",
508 "i2s3_sync",
509 "i2s4_sync",
510 "vimclk_sync",
511};
512
513#define AUDIO_SYNC_CLK(_name, _index) \
514 static struct clk tegra_##_name; \
515 static struct clk_tegra tegra_##_name##_hw = { \
516 .hw = { \
517 .clk = &tegra_##_name, \
518 }, \
519 .max_rate = 24000000, \
520 .reg = 0x4A0 + (_index) * 4, \
521 }; \
522 static struct clk tegra_##_name = { \
523 .name = #_name, \
524 .ops = &tegra30_audio_sync_clk_ops, \
525 .hw = &tegra_##_name##_hw.hw, \
526 .parent_names = mux_audio_sync_clk, \
527 .parents = tegra_sync_source_list, \
528 .num_parents = ARRAY_SIZE(mux_audio_sync_clk), \
529 };
530
531AUDIO_SYNC_CLK(audio0, 0);
532AUDIO_SYNC_CLK(audio1, 1);
533AUDIO_SYNC_CLK(audio2, 2);
534AUDIO_SYNC_CLK(audio3, 3);
535AUDIO_SYNC_CLK(audio4, 4);
536AUDIO_SYNC_CLK(audio5, 5);
537
538static struct clk *tegra_clk_audio_list[] = {
539 &tegra_audio0,
540 &tegra_audio1,
541 &tegra_audio2,
542 &tegra_audio3,
543 &tegra_audio4,
544 &tegra_audio5, /* SPDIF */
545};
546
547#define AUDIO_SYNC_2X_CLK(_name, _index) \
548 static const char *_name##_parent_names[] = { \
549 "tegra_" #_name, \
550 }; \
551 static struct clk *_name##_parents[] = { \
552 &tegra_##_name, \
553 }; \
554 static struct clk tegra_##_name##_2x; \
555 static struct clk_tegra tegra_##_name##_2x_hw = { \
556 .hw = { \
557 .clk = &tegra_##_name##_2x, \
558 }, \
559 .flags = PERIPH_NO_RESET, \
560 .max_rate = 48000000, \
561 .reg = 0x49C, \
562 .reg_shift = 24 + (_index), \
563 .u.periph = { \
564 .clk_num = 113 + (_index), \
565 }, \
566 }; \
567 static struct clk tegra_##_name##_2x = { \
568 .name = #_name "_2x", \
569 .ops = &tegra30_clk_double_ops, \
570 .hw = &tegra_##_name##_2x_hw.hw, \
571 .parent_names = _name##_parent_names, \
572 .parents = _name##_parents, \
573 .parent = &tegra_##_name, \
574 .num_parents = 1, \
575 };
576
577AUDIO_SYNC_2X_CLK(audio0, 0);
578AUDIO_SYNC_2X_CLK(audio1, 1);
579AUDIO_SYNC_2X_CLK(audio2, 2);
580AUDIO_SYNC_2X_CLK(audio3, 3);
581AUDIO_SYNC_2X_CLK(audio4, 4);
582AUDIO_SYNC_2X_CLK(audio5, 5); /* SPDIF */
583
584static struct clk *tegra_clk_audio_2x_list[] = {
585 &tegra_audio0_2x,
586 &tegra_audio1_2x,
587 &tegra_audio2_2x,
588 &tegra_audio3_2x,
589 &tegra_audio4_2x,
590 &tegra_audio5_2x, /* SPDIF */
591};
592
593#define MUX_I2S_SPDIF(_id) \
594static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { \
595 "pll_a_out0", \
596 #_id "_2x", \
597 "pll_p", \
598 "clk_m", \
599}; \
600static struct clk *mux_pllaout0_##_id##_2x_pllp_clkm_p[] = { \
601 &tegra_pll_a_out0, \
602 &tegra_##_id##_2x, \
603 &tegra_pll_p, \
604 &tegra_clk_m, \
605};
606
607MUX_I2S_SPDIF(audio0);
608MUX_I2S_SPDIF(audio1);
609MUX_I2S_SPDIF(audio2);
610MUX_I2S_SPDIF(audio3);
611MUX_I2S_SPDIF(audio4);
612MUX_I2S_SPDIF(audio5); /* SPDIF */
613
614static struct clk tegra_extern1;
615static struct clk tegra_extern2;
616static struct clk tegra_extern3;
617
618/* External clock outputs (through PMC) */
619#define MUX_EXTERN_OUT(_id) \
620static const char *mux_clkm_clkm2_clkm4_extern##_id[] = { \
621 "clk_m", \
622 "clk_m_div2", \
623 "clk_m_div4", \
624 "extern" #_id, \
625}; \
626static struct clk *mux_clkm_clkm2_clkm4_extern##_id##_p[] = { \
627 &tegra_clk_m, \
628 &tegra_clk_m_div2, \
629 &tegra_clk_m_div4, \
630 &tegra_extern##_id, \
631};
632
633MUX_EXTERN_OUT(1);
634MUX_EXTERN_OUT(2);
635MUX_EXTERN_OUT(3);
636
637#define CLK_OUT_CLK(_name, _index) \
638 static struct clk tegra_##_name; \
639 static struct clk_tegra tegra_##_name##_hw = { \
640 .hw = { \
641 .clk = &tegra_##_name, \
642 }, \
643 .lookup = { \
644 .dev_id = #_name, \
645 .con_id = "extern" #_index, \
646 }, \
647 .flags = MUX_CLK_OUT, \
648 .fixed_rate = 216000000, \
649 .reg = 0x1a8, \
650 .u.periph = { \
651 .clk_num = (_index - 1) * 8 + 2, \
652 }, \
653 }; \
654 static struct clk tegra_##_name = { \
655 .name = #_name, \
656 .ops = &tegra_clk_out_ops, \
657 .hw = &tegra_##_name##_hw.hw, \
658 .parent_names = mux_clkm_clkm2_clkm4_extern##_index, \
659 .parents = mux_clkm_clkm2_clkm4_extern##_index##_p, \
660 .num_parents = ARRAY_SIZE(mux_clkm_clkm2_clkm4_extern##_index),\
661 };
662
663CLK_OUT_CLK(clk_out_1, 1);
664CLK_OUT_CLK(clk_out_2, 2);
665CLK_OUT_CLK(clk_out_3, 3);
666
667static struct clk *tegra_clk_out_list[] = {
668 &tegra_clk_out_1,
669 &tegra_clk_out_2,
670 &tegra_clk_out_3,
671};
672
673static const char *mux_sclk[] = {
674 "clk_m",
675 "pll_c_out1",
676 "pll_p_out4",
677 "pll_p_out3",
678 "pll_p_out2",
679 "dummy",
680 "clk_32k",
681 "pll_m_out1",
682};
683
684static struct clk *mux_sclk_p[] = {
685 &tegra_clk_m,
686 &tegra_pll_c_out1,
687 &tegra_pll_p_out4,
688 &tegra_pll_p_out3,
689 &tegra_pll_p_out2,
690 NULL,
691 &tegra_clk_32k,
692 &tegra_pll_m_out1,
693};
694
695static struct clk tegra_clk_sclk;
696static struct clk_tegra tegra_clk_sclk_hw = {
697 .hw = {
698 .clk = &tegra_clk_sclk,
699 },
700 .reg = 0x28,
701 .max_rate = 334000000,
702 .min_rate = 40000000,
703};
704
705static struct clk tegra_clk_sclk = {
706 .name = "sclk",
707 .ops = &tegra30_super_ops,
708 .hw = &tegra_clk_sclk_hw.hw,
709 .parent_names = mux_sclk,
710 .parents = mux_sclk_p,
711 .num_parents = ARRAY_SIZE(mux_sclk),
712};
713
714static const char *tegra_hclk_parent_names[] = {
715 "tegra_sclk",
716};
717
718static struct clk *tegra_hclk_parents[] = {
719 &tegra_clk_sclk,
720};
721
722static struct clk tegra_hclk;
723static struct clk_tegra tegra_hclk_hw = {
724 .hw = {
725 .clk = &tegra_hclk,
726 },
727 .flags = DIV_BUS,
728 .reg = 0x30,
729 .reg_shift = 4,
730 .max_rate = 378000000,
731 .min_rate = 12000000,
732};
733DEFINE_CLK_TEGRA(hclk, 0, &tegra30_bus_ops, 0, tegra_hclk_parent_names,
734 tegra_hclk_parents, &tegra_clk_sclk);
735
736static const char *tegra_pclk_parent_names[] = {
737 "tegra_hclk",
738};
739
740static struct clk *tegra_pclk_parents[] = {
741 &tegra_hclk,
742};
743
744static struct clk tegra_pclk;
745static struct clk_tegra tegra_pclk_hw = {
746 .hw = {
747 .clk = &tegra_pclk,
748 },
749 .flags = DIV_BUS,
750 .reg = 0x30,
751 .reg_shift = 0,
752 .max_rate = 167000000,
753 .min_rate = 12000000,
754};
755DEFINE_CLK_TEGRA(pclk, 0, &tegra30_bus_ops, 0, tegra_pclk_parent_names,
756 tegra_pclk_parents, &tegra_hclk);
757
758static const char *mux_blink[] = {
759 "clk_32k",
760};
761
762static struct clk *mux_blink_p[] = {
763 &tegra_clk_32k,
764};
765
766static struct clk tegra_clk_blink;
767static struct clk_tegra tegra_clk_blink_hw = {
768 .hw = {
769 .clk = &tegra_clk_blink,
770 },
771 .reg = 0x40,
772 .max_rate = 32768,
773};
774static struct clk tegra_clk_blink = {
775 .name = "blink",
776 .ops = &tegra30_blink_clk_ops,
777 .hw = &tegra_clk_blink_hw.hw,
778 .parent = &tegra_clk_32k,
779 .parent_names = mux_blink,
780 .parents = mux_blink_p,
781 .num_parents = ARRAY_SIZE(mux_blink),
782};
783
784static const char *mux_pllm_pllc_pllp_plla[] = {
785 "pll_m",
786 "pll_c",
787 "pll_p",
788 "pll_a_out0",
789};
790
791static const char *mux_pllp_pllc_pllm_clkm[] = {
792 "pll_p",
793 "pll_c",
794 "pll_m",
795 "clk_m",
796};
797
798static const char *mux_pllp_clkm[] = {
799 "pll_p",
800 "dummy",
801 "dummy",
802 "clk_m",
803};
804
805static const char *mux_pllp_plld_pllc_clkm[] = {
806 "pll_p",
807 "pll_d_out0",
808 "pll_c",
809 "clk_m",
810};
811
812static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
813 "pll_p",
814 "pll_m",
815 "pll_d_out0",
816 "pll_a_out0",
817 "pll_c",
818 "pll_d2_out0",
819 "clk_m",
820};
821
822static const char *mux_plla_pllc_pllp_clkm[] = {
823 "pll_a_out0",
824 "dummy",
825 "pll_p",
826 "clk_m"
827};
828
829static const char *mux_pllp_pllc_clk32_clkm[] = {
830 "pll_p",
831 "pll_c",
832 "clk_32k",
833 "clk_m",
834};
835
836static const char *mux_pllp_pllc_clkm_clk32[] = {
837 "pll_p",
838 "pll_c",
839 "clk_m",
840 "clk_32k",
841};
842
843static const char *mux_pllp_pllc_pllm[] = {
844 "pll_p",
845 "pll_c",
846 "pll_m",
847};
848
849static const char *mux_clk_m[] = {
850 "clk_m",
851};
852
853static const char *mux_pllp_out3[] = {
854 "pll_p_out3",
855};
856
857static const char *mux_plld_out0[] = {
858 "pll_d_out0",
859};
860
861static const char *mux_plld_out0_plld2_out0[] = {
862 "pll_d_out0",
863 "pll_d2_out0",
864};
865
866static const char *mux_clk_32k[] = {
867 "clk_32k",
868};
869
870static const char *mux_plla_clk32_pllp_clkm_plle[] = {
871 "pll_a_out0",
872 "clk_32k",
873 "pll_p",
874 "clk_m",
875 "pll_e",
876};
877
878static const char *mux_cclk_g[] = {
879 "clk_m",
880 "pll_c",
881 "clk_32k",
882 "pll_m",
883 "pll_p",
884 "pll_p_out4",
885 "pll_p_out3",
886 "dummy",
887 "pll_x",
888};
889
890static struct clk *mux_pllm_pllc_pllp_plla_p[] = {
891 &tegra_pll_m,
892 &tegra_pll_c,
893 &tegra_pll_p,
894 &tegra_pll_a_out0,
895};
896
897static struct clk *mux_pllp_pllc_pllm_clkm_p[] = {
898 &tegra_pll_p,
899 &tegra_pll_c,
900 &tegra_pll_m,
901 &tegra_clk_m,
902};
903
904static struct clk *mux_pllp_clkm_p[] = {
905 &tegra_pll_p,
906 NULL,
907 NULL,
908 &tegra_clk_m,
909};
910
911static struct clk *mux_pllp_plld_pllc_clkm_p[] = {
912 &tegra_pll_p,
913 &tegra_pll_d_out0,
914 &tegra_pll_c,
915 &tegra_clk_m,
916};
917
918static struct clk *mux_pllp_pllm_plld_plla_pllc_plld2_clkm_p[] = {
919 &tegra_pll_p,
920 &tegra_pll_m,
921 &tegra_pll_d_out0,
922 &tegra_pll_a_out0,
923 &tegra_pll_c,
924 &tegra_pll_d2_out0,
925 &tegra_clk_m,
926};
927
928static struct clk *mux_plla_pllc_pllp_clkm_p[] = {
929 &tegra_pll_a_out0,
930 NULL,
931 &tegra_pll_p,
932 &tegra_clk_m,
933};
934
935static struct clk *mux_pllp_pllc_clk32_clkm_p[] = {
936 &tegra_pll_p,
937 &tegra_pll_c,
938 &tegra_clk_32k,
939 &tegra_clk_m,
940};
941
942static struct clk *mux_pllp_pllc_clkm_clk32_p[] = {
943 &tegra_pll_p,
944 &tegra_pll_c,
945 &tegra_clk_m,
946 &tegra_clk_32k,
947};
948
949static struct clk *mux_pllp_pllc_pllm_p[] = {
950 &tegra_pll_p,
951 &tegra_pll_c,
952 &tegra_pll_m,
953};
954
955static struct clk *mux_clk_m_p[] = {
956 &tegra_clk_m,
957};
958
959static struct clk *mux_pllp_out3_p[] = {
960 &tegra_pll_p_out3,
961};
962
963static struct clk *mux_plld_out0_p[] = {
964 &tegra_pll_d_out0,
965};
966
967static struct clk *mux_plld_out0_plld2_out0_p[] = {
968 &tegra_pll_d_out0,
969 &tegra_pll_d2_out0,
970};
971
972static struct clk *mux_clk_32k_p[] = {
973 &tegra_clk_32k,
974};
975
976static struct clk *mux_plla_clk32_pllp_clkm_plle_p[] = {
977 &tegra_pll_a_out0,
978 &tegra_clk_32k,
979 &tegra_pll_p,
980 &tegra_clk_m,
981 &tegra_pll_e,
982};
983
984static struct clk *mux_cclk_g_p[] = {
985 &tegra_clk_m,
986 &tegra_pll_c,
987 &tegra_clk_32k,
988 &tegra_pll_m,
989 &tegra_pll_p,
990 &tegra_pll_p_out4,
991 &tegra_pll_p_out3,
992 NULL,
993 &tegra_pll_x,
994};
995
996static struct clk tegra_clk_cclk_g;
997static struct clk_tegra tegra_clk_cclk_g_hw = {
998 .hw = {
999 .clk = &tegra_clk_cclk_g,
1000 },
1001 .flags = DIV_U71 | DIV_U71_INT,
1002 .reg = 0x368,
1003 .max_rate = 1700000000,
1004};
1005static struct clk tegra_clk_cclk_g = {
1006 .name = "cclk_g",
1007 .ops = &tegra30_super_ops,
1008 .hw = &tegra_clk_cclk_g_hw.hw,
1009 .parent_names = mux_cclk_g,
1010 .parents = mux_cclk_g_p,
1011 .num_parents = ARRAY_SIZE(mux_cclk_g),
1012};
1013
1014static const char *mux_twd[] = {
1015 "cclk_g",
1016};
1017
1018static struct clk *mux_twd_p[] = {
1019 &tegra_clk_cclk_g,
1020};
1021
1022static struct clk tegra30_clk_twd;
1023static struct clk_tegra tegra30_clk_twd_hw = {
1024 .hw = {
1025 .clk = &tegra30_clk_twd,
1026 },
1027 .max_rate = 1400000000,
1028 .mul = 1,
1029 .div = 2,
1030};
1031
1032static struct clk tegra30_clk_twd = {
1033 .name = "twd",
1034 .ops = &tegra30_twd_ops,
1035 .hw = &tegra30_clk_twd_hw.hw,
1036 .parent = &tegra_clk_cclk_g,
1037 .parent_names = mux_twd,
1038 .parents = mux_twd_p,
1039 .num_parents = ARRAY_SIZE(mux_twd),
1040};
1041
1042#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, \
1043 _max, _inputs, _flags) \
1044 static struct clk tegra_##_name; \
1045 static struct clk_tegra tegra_##_name##_hw = { \
1046 .hw = { \
1047 .clk = &tegra_##_name, \
1048 }, \
1049 .lookup = { \
1050 .dev_id = _dev, \
1051 .con_id = _con, \
1052 }, \
1053 .reg = _reg, \
1054 .flags = _flags, \
1055 .max_rate = _max, \
1056 .u.periph = { \
1057 .clk_num = _clk_num, \
1058 }, \
1059 .reset = &tegra30_periph_clk_reset, \
1060 }; \
1061 static struct clk tegra_##_name = { \
1062 .name = #_name, \
1063 .ops = &tegra30_periph_clk_ops, \
1064 .hw = &tegra_##_name##_hw.hw, \
1065 .parent_names = _inputs, \
1066 .parents = _inputs##_p, \
1067 .num_parents = ARRAY_SIZE(_inputs), \
1068 };
1069
1070PERIPH_CLK(apbdma, "tegra-apbdma", NULL, 34, 0, 26000000, mux_clk_m, 0);
1071PERIPH_CLK(rtc, "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB);
1072PERIPH_CLK(kbc, "tegra-kbc", NULL, 36, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB);
1073PERIPH_CLK(timer, "timer", NULL, 5, 0, 26000000, mux_clk_m, 0);
1074PERIPH_CLK(kfuse, "kfuse-tegra", NULL, 40, 0, 26000000, mux_clk_m, 0);
1075PERIPH_CLK(fuse, "fuse-tegra", "fuse", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB);
1076PERIPH_CLK(fuse_burn, "fuse-tegra", "fuse_burn", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB);
1077PERIPH_CLK(apbif, "tegra30-ahub", "apbif", 107, 0, 26000000, mux_clk_m, 0);
1078PERIPH_CLK(i2s0, "tegra30-i2s.0", NULL, 30, 0x1d8, 26000000, mux_pllaout0_audio0_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1079PERIPH_CLK(i2s1, "tegra30-i2s.1", NULL, 11, 0x100, 26000000, mux_pllaout0_audio1_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1080PERIPH_CLK(i2s2, "tegra30-i2s.2", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1081PERIPH_CLK(i2s3, "tegra30-i2s.3", NULL, 101, 0x3bc, 26000000, mux_pllaout0_audio3_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1082PERIPH_CLK(i2s4, "tegra30-i2s.4", NULL, 102, 0x3c0, 26000000, mux_pllaout0_audio4_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1083PERIPH_CLK(spdif_out, "tegra30-spdif", "spdif_out", 10, 0x108, 100000000, mux_pllaout0_audio5_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1084PERIPH_CLK(spdif_in, "tegra30-spdif", "spdif_in", 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71 | PERIPH_ON_APB);
1085PERIPH_CLK(pwm, "tegra-pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_clk32_clkm, MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB);
1086PERIPH_CLK(d_audio, "tegra30-ahub", "d_audio", 106, 0x3d0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71);
1087PERIPH_CLK(dam0, "tegra30-dam.0", NULL, 108, 0x3d8, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71);
1088PERIPH_CLK(dam1, "tegra30-dam.1", NULL, 109, 0x3dc, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71);
1089PERIPH_CLK(dam2, "tegra30-dam.2", NULL, 110, 0x3e0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71);
1090PERIPH_CLK(hda, "tegra30-hda", "hda", 125, 0x428, 108000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
1091PERIPH_CLK(hda2codec_2x, "tegra30-hda", "hda2codec", 111, 0x3e4, 48000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
1092PERIPH_CLK(hda2hdmi, "tegra30-hda", "hda2hdmi", 128, 0, 48000000, mux_clk_m, 0);
1093PERIPH_CLK(sbc1, "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1094PERIPH_CLK(sbc2, "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1095PERIPH_CLK(sbc3, "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1096PERIPH_CLK(sbc4, "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1097PERIPH_CLK(sbc5, "spi_tegra.4", NULL, 104, 0x3c8, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1098PERIPH_CLK(sbc6, "spi_tegra.5", NULL, 105, 0x3cc, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1099PERIPH_CLK(sata_oob, "tegra_sata_oob", NULL, 123, 0x420, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
1100PERIPH_CLK(sata, "tegra_sata", NULL, 124, 0x424, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
1101PERIPH_CLK(sata_cold, "tegra_sata_cold", NULL, 129, 0, 48000000, mux_clk_m, 0);
1102PERIPH_CLK(ndflash, "tegra_nand", NULL, 13, 0x160, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
1103PERIPH_CLK(ndspeed, "tegra_nand_speed", NULL, 80, 0x3f8, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
1104PERIPH_CLK(vfir, "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1105PERIPH_CLK(sdmmc1, "sdhci-tegra.0", NULL, 14, 0x150, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
1106PERIPH_CLK(sdmmc2, "sdhci-tegra.1", NULL, 9, 0x154, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
1107PERIPH_CLK(sdmmc3, "sdhci-tegra.2", NULL, 69, 0x1bc, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
1108PERIPH_CLK(sdmmc4, "sdhci-tegra.3", NULL, 15, 0x164, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */
1109PERIPH_CLK(vcp, "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0);
1110PERIPH_CLK(bsea, "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0);
1111PERIPH_CLK(bsev, "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0);
1112PERIPH_CLK(vde, "vde", NULL, 61, 0x1c8, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT);
1113PERIPH_CLK(csite, "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* max rate ??? */
1114PERIPH_CLK(la, "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
1115PERIPH_CLK(owr, "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1116PERIPH_CLK(nor, "nor", NULL, 42, 0x1d0, 127000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* requires min voltage */
1117PERIPH_CLK(mipi, "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); /* scales with voltage */
1118PERIPH_CLK(i2c1, "tegra-i2c.0", "div-clk", 12, 0x124, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB);
1119PERIPH_CLK(i2c2, "tegra-i2c.1", "div-clk", 54, 0x198, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB);
1120PERIPH_CLK(i2c3, "tegra-i2c.2", "div-clk", 67, 0x1b8, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB);
1121PERIPH_CLK(i2c4, "tegra-i2c.3", "div-clk", 103, 0x3c4, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB);
1122PERIPH_CLK(i2c5, "tegra-i2c.4", "div-clk", 47, 0x128, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB);
1123PERIPH_CLK(uarta, "tegra-uart.0", NULL, 6, 0x178, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
1124PERIPH_CLK(uartb, "tegra-uart.1", NULL, 7, 0x17c, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
1125PERIPH_CLK(uartc, "tegra-uart.2", NULL, 55, 0x1a0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
1126PERIPH_CLK(uartd, "tegra-uart.3", NULL, 65, 0x1c0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
1127PERIPH_CLK(uarte, "tegra-uart.4", NULL, 66, 0x1c4, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
1128PERIPH_CLK(vi, "tegra_camera", "vi", 20, 0x148, 425000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT);
1129PERIPH_CLK(3d, "3d", NULL, 24, 0x158, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET);
1130PERIPH_CLK(3d2, "3d2", NULL, 98, 0x3b0, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET);
1131PERIPH_CLK(2d, "2d", NULL, 21, 0x15c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE);
1132PERIPH_CLK(vi_sensor, "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET);
1133PERIPH_CLK(epp, "epp", NULL, 19, 0x16c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT);
1134PERIPH_CLK(mpe, "mpe", NULL, 60, 0x170, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT);
1135PERIPH_CLK(host1x, "host1x", NULL, 28, 0x180, 260000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT);
1136PERIPH_CLK(cve, "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */
1137PERIPH_CLK(tvo, "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */
1138PERIPH_CLK(dtv, "dtv", NULL, 79, 0x1dc, 250000000, mux_clk_m, 0);
1139PERIPH_CLK(hdmi, "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8 | DIV_U71);
1140PERIPH_CLK(tvdac, "tvdac", NULL, 53, 0x194, 220000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */
1141PERIPH_CLK(disp1, "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8);
1142PERIPH_CLK(disp2, "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8);
1143PERIPH_CLK(usbd, "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0); /* requires min voltage */
1144PERIPH_CLK(usb2, "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0); /* requires min voltage */
1145PERIPH_CLK(usb3, "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0); /* requires min voltage */
1146PERIPH_CLK(dsia, "tegradc.0", "dsia", 48, 0, 500000000, mux_plld_out0, 0);
1147PERIPH_CLK(csi, "tegra_camera", "csi", 52, 0, 102000000, mux_pllp_out3, 0);
1148PERIPH_CLK(isp, "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0); /* same frequency as VI */
1149PERIPH_CLK(csus, "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET);
1150PERIPH_CLK(tsensor, "tegra-tsensor", NULL, 100, 0x3b8, 216000000, mux_pllp_pllc_clkm_clk32, MUX | DIV_U71);
1151PERIPH_CLK(actmon, "actmon", NULL, 119, 0x3e8, 216000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71);
1152PERIPH_CLK(extern1, "extern1", NULL, 120, 0x3ec, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71);
1153PERIPH_CLK(extern2, "extern2", NULL, 121, 0x3f0, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71);
1154PERIPH_CLK(extern3, "extern3", NULL, 122, 0x3f4, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71);
1155PERIPH_CLK(i2cslow, "i2cslow", NULL, 81, 0x3fc, 26000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
1156PERIPH_CLK(pcie, "tegra-pcie", "pcie", 70, 0, 250000000, mux_clk_m, 0);
1157PERIPH_CLK(afi, "tegra-pcie", "afi", 72, 0, 250000000, mux_clk_m, 0);
1158PERIPH_CLK(se, "se", NULL, 127, 0x42c, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT);
1159
1160static struct clk tegra_dsib;
1161static struct clk_tegra tegra_dsib_hw = {
1162 .hw = {
1163 .clk = &tegra_dsib,
1164 },
1165 .lookup = {
1166 .dev_id = "tegradc.1",
1167 .con_id = "dsib",
1168 },
1169 .reg = 0xd0,
1170 .flags = MUX | PLLD,
1171 .max_rate = 500000000,
1172 .u.periph = {
1173 .clk_num = 82,
1174 },
1175 .reset = &tegra30_periph_clk_reset,
1176};
1177static struct clk tegra_dsib = {
1178 .name = "dsib",
1179 .ops = &tegra30_dsib_clk_ops,
1180 .hw = &tegra_dsib_hw.hw,
1181 .parent_names = mux_plld_out0_plld2_out0,
1182 .parents = mux_plld_out0_plld2_out0_p,
1183 .num_parents = ARRAY_SIZE(mux_plld_out0_plld2_out0),
1184};
1185
1186static struct clk *tegra_list_clks[] = {
1187 &tegra_apbdma,
1188 &tegra_rtc,
1189 &tegra_kbc,
1190 &tegra_timer,
1191 &tegra_kfuse,
1192 &tegra_fuse,
1193 &tegra_fuse_burn,
1194 &tegra_apbif,
1195 &tegra_i2s0,
1196 &tegra_i2s1,
1197 &tegra_i2s2,
1198 &tegra_i2s3,
1199 &tegra_i2s4,
1200 &tegra_spdif_out,
1201 &tegra_spdif_in,
1202 &tegra_pwm,
1203 &tegra_d_audio,
1204 &tegra_dam0,
1205 &tegra_dam1,
1206 &tegra_dam2,
1207 &tegra_hda,
1208 &tegra_hda2codec_2x,
1209 &tegra_hda2hdmi,
1210 &tegra_sbc1,
1211 &tegra_sbc2,
1212 &tegra_sbc3,
1213 &tegra_sbc4,
1214 &tegra_sbc5,
1215 &tegra_sbc6,
1216 &tegra_sata_oob,
1217 &tegra_sata,
1218 &tegra_sata_cold,
1219 &tegra_ndflash,
1220 &tegra_ndspeed,
1221 &tegra_vfir,
1222 &tegra_sdmmc1,
1223 &tegra_sdmmc2,
1224 &tegra_sdmmc3,
1225 &tegra_sdmmc4,
1226 &tegra_vcp,
1227 &tegra_bsea,
1228 &tegra_bsev,
1229 &tegra_vde,
1230 &tegra_csite,
1231 &tegra_la,
1232 &tegra_owr,
1233 &tegra_nor,
1234 &tegra_mipi,
1235 &tegra_i2c1,
1236 &tegra_i2c2,
1237 &tegra_i2c3,
1238 &tegra_i2c4,
1239 &tegra_i2c5,
1240 &tegra_uarta,
1241 &tegra_uartb,
1242 &tegra_uartc,
1243 &tegra_uartd,
1244 &tegra_uarte,
1245 &tegra_vi,
1246 &tegra_3d,
1247 &tegra_3d2,
1248 &tegra_2d,
1249 &tegra_vi_sensor,
1250 &tegra_epp,
1251 &tegra_mpe,
1252 &tegra_host1x,
1253 &tegra_cve,
1254 &tegra_tvo,
1255 &tegra_dtv,
1256 &tegra_hdmi,
1257 &tegra_tvdac,
1258 &tegra_disp1,
1259 &tegra_disp2,
1260 &tegra_usbd,
1261 &tegra_usb2,
1262 &tegra_usb3,
1263 &tegra_dsia,
1264 &tegra_dsib,
1265 &tegra_csi,
1266 &tegra_isp,
1267 &tegra_csus,
1268 &tegra_tsensor,
1269 &tegra_actmon,
1270 &tegra_extern1,
1271 &tegra_extern2,
1272 &tegra_extern3,
1273 &tegra_i2cslow,
1274 &tegra_pcie,
1275 &tegra_afi,
1276 &tegra_se,
1277};
1278
1279#define CLK_DUPLICATE(_name, _dev, _con) \
1280 { \
1281 .name = _name, \
1282 .lookup = { \
1283 .dev_id = _dev, \
1284 .con_id = _con, \
1285 }, \
1286 }
1287
1288/* Some clocks may be used by different drivers depending on the board
1289 * configuration. List those here to register them twice in the clock lookup
1290 * table under two names.
1291 */
1292static struct clk_duplicate tegra_clk_duplicates[] = {
1293 CLK_DUPLICATE("uarta", "serial8250.0", NULL),
1294 CLK_DUPLICATE("uartb", "serial8250.1", NULL),
1295 CLK_DUPLICATE("uartc", "serial8250.2", NULL),
1296 CLK_DUPLICATE("uartd", "serial8250.3", NULL),
1297 CLK_DUPLICATE("uarte", "serial8250.4", NULL),
1298 CLK_DUPLICATE("usbd", "utmip-pad", NULL),
1299 CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
1300 CLK_DUPLICATE("usbd", "tegra-otg", NULL),
1301 CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
1302 CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
1303 CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
1304 CLK_DUPLICATE("bsev", "nvavp", "bsev"),
1305 CLK_DUPLICATE("vde", "tegra-aes", "vde"),
1306 CLK_DUPLICATE("bsea", "tegra-aes", "bsea"),
1307 CLK_DUPLICATE("bsea", "nvavp", "bsea"),
1308 CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL),
1309 CLK_DUPLICATE("cml0", "tegra_pcie", "cml"),
1310 CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"),
1311 CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL),
1312 CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL),
1313 CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL),
1314 CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL),
1315 CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL),
1316 CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL),
1317 CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL),
1318 CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL),
1319 CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL),
1320 CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL),
1321 CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
1322 CLK_DUPLICATE("twd", "smp_twd", NULL),
1323 CLK_DUPLICATE("vcp", "nvavp", "vcp"),
1324 CLK_DUPLICATE("i2s0", NULL, "i2s0"),
1325 CLK_DUPLICATE("i2s1", NULL, "i2s1"),
1326 CLK_DUPLICATE("i2s2", NULL, "i2s2"),
1327 CLK_DUPLICATE("i2s3", NULL, "i2s3"),
1328 CLK_DUPLICATE("i2s4", NULL, "i2s4"),
1329 CLK_DUPLICATE("dam0", NULL, "dam0"),
1330 CLK_DUPLICATE("dam1", NULL, "dam1"),
1331 CLK_DUPLICATE("dam2", NULL, "dam2"),
1332 CLK_DUPLICATE("spdif_in", NULL, "spdif_in"),
1333 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.0", "fast-clk"),
1334 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.1", "fast-clk"),
1335 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"),
1336 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"),
1337 CLK_DUPLICATE("pll_p_out3", "tegra-i2c.4", "fast-clk"),
1338 CLK_DUPLICATE("pll_p", "tegradc.0", "parent"),
1339 CLK_DUPLICATE("pll_p", "tegradc.1", "parent"),
1340 CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"),
1341};
1342
1343static struct clk *tegra_ptr_clks[] = {
1344 &tegra_clk_32k,
1345 &tegra_clk_m,
1346 &tegra_clk_m_div2,
1347 &tegra_clk_m_div4,
1348 &tegra_pll_ref,
1349 &tegra_pll_m,
1350 &tegra_pll_m_out1,
1351 &tegra_pll_c,
1352 &tegra_pll_c_out1,
1353 &tegra_pll_p,
1354 &tegra_pll_p_out1,
1355 &tegra_pll_p_out2,
1356 &tegra_pll_p_out3,
1357 &tegra_pll_p_out4,
1358 &tegra_pll_a,
1359 &tegra_pll_a_out0,
1360 &tegra_pll_d,
1361 &tegra_pll_d_out0,
1362 &tegra_pll_d2,
1363 &tegra_pll_d2_out0,
1364 &tegra_pll_u,
1365 &tegra_pll_x,
1366 &tegra_pll_x_out0,
1367 &tegra_pll_e,
1368 &tegra_clk_cclk_g,
1369 &tegra_cml0,
1370 &tegra_cml1,
1371 &tegra_pciex,
1372 &tegra_clk_sclk,
1373 &tegra_hclk,
1374 &tegra_pclk,
1375 &tegra_clk_blink,
1376 &tegra30_clk_twd,
1377};
1378
1379static void tegra30_init_one_clock(struct clk *c)
1380{
1381 struct clk_tegra *clk = to_clk_tegra(c->hw);
1382 __clk_init(NULL, c);
1383 INIT_LIST_HEAD(&clk->shared_bus_list);
1384 if (!clk->lookup.dev_id && !clk->lookup.con_id)
1385 clk->lookup.con_id = c->name;
1386 clk->lookup.clk = c;
1387 clkdev_add(&clk->lookup);
1388 tegra_clk_add(c);
1389}
1390
1391void __init tegra30_init_clocks(void)
1392{
1393 int i;
1394 struct clk *c;
1395
1396 for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
1397 tegra30_init_one_clock(tegra_ptr_clks[i]);
1398
1399 for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
1400 tegra30_init_one_clock(tegra_list_clks[i]);
1401
1402 for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
1403 c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
1404 if (!c) {
1405 pr_err("%s: Unknown duplicate clock %s\n", __func__,
1406 tegra_clk_duplicates[i].name);
1407 continue;
1408 }
1409
1410 tegra_clk_duplicates[i].lookup.clk = c;
1411 clkdev_add(&tegra_clk_duplicates[i].lookup);
1412 }
1413
1414 for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++)
1415 tegra30_init_one_clock(tegra_sync_source_list[i]);
1416 for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++)
1417 tegra30_init_one_clock(tegra_clk_audio_list[i]);
1418 for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++)
1419 tegra30_init_one_clock(tegra_clk_audio_2x_list[i]);
1420
1421 for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++)
1422 tegra30_init_one_clock(tegra_clk_out_list[i]);
1423
1424 tegra30_cpu_car_ops_init();
1425}
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
index 7a602069bab9..e3e94b2fa145 100644
--- a/arch/arm/mach-vt8500/Kconfig
+++ b/arch/arm/mach-vt8500/Kconfig
@@ -16,3 +16,19 @@ config ARCH_WM8505
16 select ARCH_VT8500 16 select ARCH_VT8500
17 select CPU_ARM926T 17 select CPU_ARM926T
18 help 18 help
19
20config ARCH_WM8750
21 bool "WonderMedia WM8750"
22 depends on ARCH_MULTI_V6
23 select ARCH_VT8500
24 select CPU_V6
25 help
26 Support for WonderMedia WM8750 System-on-Chip.
27
28config ARCH_WM8850
29 bool "WonderMedia WM8850"
30 depends on ARCH_MULTI_V7
31 select ARCH_VT8500
32 select CPU_V7
33 help
34 Support for WonderMedia WM8850 System-on-Chip.
diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c
index fe99b709f11f..49e80053d828 100644
--- a/arch/arm/mach-vt8500/vt8500.c
+++ b/arch/arm/mach-vt8500/vt8500.c
@@ -180,6 +180,8 @@ static const char * const vt8500_dt_compat[] = {
180 "via,vt8500", 180 "via,vt8500",
181 "wm,wm8650", 181 "wm,wm8650",
182 "wm,wm8505", 182 "wm,wm8505",
183 "wm,wm8750",
184 "wm,wm8850",
183}; 185};
184 186
185DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)") 187DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)")
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 7539ec275065..15451ee4acc8 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -19,6 +19,52 @@
19#include "proc-macros.S" 19#include "proc-macros.S"
20 20
21/* 21/*
22 * The secondary kernel init calls v7_flush_dcache_all before it enables
23 * the L1; however, the L1 comes out of reset in an undefined state, so
24 * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
25 * of cache lines with uninitialized data and uninitialized tags to get
26 * written out to memory, which does really unpleasant things to the main
27 * processor. We fix this by performing an invalidate, rather than a
28 * clean + invalidate, before jumping into the kernel.
29 *
30 * This function is cloned from arch/arm/mach-tegra/headsmp.S, and needs
31 * to be called for both secondary cores startup and primary core resume
32 * procedures.
33 */
34ENTRY(v7_invalidate_l1)
35 mov r0, #0
36 mcr p15, 2, r0, c0, c0, 0
37 mrc p15, 1, r0, c0, c0, 0
38
39 ldr r1, =0x7fff
40 and r2, r1, r0, lsr #13
41
42 ldr r1, =0x3ff
43
44 and r3, r1, r0, lsr #3 @ NumWays - 1
45 add r2, r2, #1 @ NumSets
46
47 and r0, r0, #0x7
48 add r0, r0, #4 @ SetShift
49
50 clz r1, r3 @ WayShift
51 add r4, r3, #1 @ NumWays
521: sub r2, r2, #1 @ NumSets--
53 mov r3, r4 @ Temp = NumWays
542: subs r3, r3, #1 @ Temp--
55 mov r5, r3, lsl r1
56 mov r6, r2, lsl r0
57 orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
58 mcr p15, 0, r5, c7, c6, 2
59 bgt 2b
60 cmp r2, #0
61 bgt 1b
62 dsb
63 isb
64 mov pc, lr
65ENDPROC(v7_invalidate_l1)
66
67/*
22 * v7_flush_icache_all() 68 * v7_flush_icache_all()
23 * 69 *
24 * Flush the whole I-cache. 70 * Flush the whole I-cache.
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 14fde73ea6ff..300d4775d926 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -26,6 +26,8 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
26obj-$(CONFIG_ARCH_U8500) += ux500/ 26obj-$(CONFIG_ARCH_U8500) += ux500/
27obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o 27obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
28obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o 28obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o
29obj-$(CONFIG_ARCH_TEGRA) += tegra/
30
29obj-$(CONFIG_X86) += x86/ 31obj-$(CONFIG_X86) += x86/
30 32
31# Chip specific 33# Chip specific
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c
index e69991aab43a..792bc57a9db7 100644
--- a/drivers/clk/clk-bcm2835.c
+++ b/drivers/clk/clk-bcm2835.c
@@ -20,6 +20,13 @@
20#include <linux/clk-provider.h> 20#include <linux/clk-provider.h>
21#include <linux/clkdev.h> 21#include <linux/clkdev.h>
22#include <linux/clk/bcm2835.h> 22#include <linux/clk/bcm2835.h>
23#include <linux/clk-provider.h>
24#include <linux/of.h>
25
26static const __initconst struct of_device_id clk_match[] = {
27 { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
28 { }
29};
23 30
24/* 31/*
25 * These are fixed clocks. They're probably not all root clocks and it may 32 * These are fixed clocks. They're probably not all root clocks and it may
@@ -56,4 +63,6 @@ void __init bcm2835_init_clocks(void)
56 ret = clk_register_clkdev(clk, NULL, "20215000.uart"); 63 ret = clk_register_clkdev(clk, NULL, "20215000.uart");
57 if (ret) 64 if (ret)
58 pr_err("uart1_pclk alias not registered\n"); 65 pr_err("uart1_pclk alias not registered\n");
66
67 of_clk_init(clk_match);
59} 68}
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c
index 126370a62ce2..76ce6c6d1113 100644
--- a/drivers/clk/mxs/clk-imx28.c
+++ b/drivers/clk/mxs/clk-imx28.c
@@ -238,7 +238,7 @@ int __init mx28_clocks_init(void)
238 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 238 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
239 } 239 }
240 240
241 clk_register_clkdev(clks[clk32k], NULL, "timrot"); 241 clk_register_clkdev(clks[xbus], NULL, "timrot");
242 clk_register_clkdev(clks[enet_out], NULL, "enet_out"); 242 clk_register_clkdev(clks[enet_out], NULL, "enet_out");
243 243
244 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) 244 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
new file mode 100644
index 000000000000..2b41b0f4f731
--- /dev/null
+++ b/drivers/clk/tegra/Makefile
@@ -0,0 +1,11 @@
1obj-y += clk.o
2obj-y += clk-audio-sync.o
3obj-y += clk-divider.o
4obj-y += clk-periph.o
5obj-y += clk-periph-gate.o
6obj-y += clk-pll.o
7obj-y += clk-pll-out.o
8obj-y += clk-super.o
9
10obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o
11obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o
diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c
new file mode 100644
index 000000000000..c0f7843e80e6
--- /dev/null
+++ b/drivers/clk/tegra/clk-audio-sync.c
@@ -0,0 +1,87 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/clk-provider.h>
18#include <linux/slab.h>
19#include <linux/err.h>
20
21#include "clk.h"
22
23static unsigned long clk_sync_source_recalc_rate(struct clk_hw *hw,
24 unsigned long parent_rate)
25{
26 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
27
28 return sync->rate;
29}
30
31static long clk_sync_source_round_rate(struct clk_hw *hw, unsigned long rate,
32 unsigned long *prate)
33{
34 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
35
36 if (rate > sync->max_rate)
37 return -EINVAL;
38 else
39 return rate;
40}
41
42static int clk_sync_source_set_rate(struct clk_hw *hw, unsigned long rate,
43 unsigned long parent_rate)
44{
45 struct tegra_clk_sync_source *sync = to_clk_sync_source(hw);
46
47 sync->rate = rate;
48 return 0;
49}
50
51const struct clk_ops tegra_clk_sync_source_ops = {
52 .round_rate = clk_sync_source_round_rate,
53 .set_rate = clk_sync_source_set_rate,
54 .recalc_rate = clk_sync_source_recalc_rate,
55};
56
57struct clk *tegra_clk_register_sync_source(const char *name,
58 unsigned long rate, unsigned long max_rate)
59{
60 struct tegra_clk_sync_source *sync;
61 struct clk_init_data init;
62 struct clk *clk;
63
64 sync = kzalloc(sizeof(*sync), GFP_KERNEL);
65 if (!sync) {
66 pr_err("%s: could not allocate sync source clk\n", __func__);
67 return ERR_PTR(-ENOMEM);
68 }
69
70 sync->rate = rate;
71 sync->max_rate = max_rate;
72
73 init.ops = &tegra_clk_sync_source_ops;
74 init.name = name;
75 init.flags = CLK_IS_ROOT;
76 init.parent_names = NULL;
77 init.num_parents = 0;
78
79 /* Data in .init is copied by clk_register(), so stack variable OK */
80 sync->hw.init = &init;
81
82 clk = clk_register(NULL, &sync->hw);
83 if (IS_ERR(clk))
84 kfree(sync);
85
86 return clk;
87}
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
new file mode 100644
index 000000000000..4d75b1f37e3a
--- /dev/null
+++ b/drivers/clk/tegra/clk-divider.c
@@ -0,0 +1,187 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/kernel.h>
18#include <linux/io.h>
19#include <linux/err.h>
20#include <linux/slab.h>
21#include <linux/clk-provider.h>
22#include <linux/clk.h>
23
24#include "clk.h"
25
26#define pll_out_override(p) (BIT((p->shift - 6)))
27#define div_mask(d) ((1 << (d->width)) - 1)
28#define get_mul(d) (1 << d->frac_width)
29#define get_max_div(d) div_mask(d)
30
31#define PERIPH_CLK_UART_DIV_ENB BIT(24)
32
33static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate,
34 unsigned long parent_rate)
35{
36 s64 divider_ux1 = parent_rate;
37 u8 flags = divider->flags;
38 int mul;
39
40 if (!rate)
41 return 0;
42
43 mul = get_mul(divider);
44
45 if (!(flags & TEGRA_DIVIDER_INT))
46 divider_ux1 *= mul;
47
48 if (flags & TEGRA_DIVIDER_ROUND_UP)
49 divider_ux1 += rate - 1;
50
51 do_div(divider_ux1, rate);
52
53 if (flags & TEGRA_DIVIDER_INT)
54 divider_ux1 *= mul;
55
56 divider_ux1 -= mul;
57
58 if (divider_ux1 < 0)
59 return 0;
60
61 if (divider_ux1 > get_max_div(divider))
62 return -EINVAL;
63
64 return divider_ux1;
65}
66
67static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw,
68 unsigned long parent_rate)
69{
70 struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
71 u32 reg;
72 int div, mul;
73 u64 rate = parent_rate;
74
75 reg = readl_relaxed(divider->reg) >> divider->shift;
76 div = reg & div_mask(divider);
77
78 mul = get_mul(divider);
79 div += mul;
80
81 rate *= mul;
82 rate += div - 1;
83 do_div(rate, div);
84
85 return rate;
86}
87
88static long clk_frac_div_round_rate(struct clk_hw *hw, unsigned long rate,
89 unsigned long *prate)
90{
91 struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
92 int div, mul;
93 unsigned long output_rate = *prate;
94
95 if (!rate)
96 return output_rate;
97
98 div = get_div(divider, rate, output_rate);
99 if (div < 0)
100 return *prate;
101
102 mul = get_mul(divider);
103
104 return DIV_ROUND_UP(output_rate * mul, div + mul);
105}
106
107static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate,
108 unsigned long parent_rate)
109{
110 struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
111 int div;
112 unsigned long flags = 0;
113 u32 val;
114
115 div = get_div(divider, rate, parent_rate);
116 if (div < 0)
117 return div;
118
119 if (divider->lock)
120 spin_lock_irqsave(divider->lock, flags);
121
122 val = readl_relaxed(divider->reg);
123 val &= ~(div_mask(divider) << divider->shift);
124 val |= div << divider->shift;
125
126 if (divider->flags & TEGRA_DIVIDER_UART) {
127 if (div)
128 val |= PERIPH_CLK_UART_DIV_ENB;
129 else
130 val &= ~PERIPH_CLK_UART_DIV_ENB;
131 }
132
133 if (divider->flags & TEGRA_DIVIDER_FIXED)
134 val |= pll_out_override(divider);
135
136 writel_relaxed(val, divider->reg);
137
138 if (divider->lock)
139 spin_unlock_irqrestore(divider->lock, flags);
140
141 return 0;
142}
143
144const struct clk_ops tegra_clk_frac_div_ops = {
145 .recalc_rate = clk_frac_div_recalc_rate,
146 .set_rate = clk_frac_div_set_rate,
147 .round_rate = clk_frac_div_round_rate,
148};
149
150struct clk *tegra_clk_register_divider(const char *name,
151 const char *parent_name, void __iomem *reg,
152 unsigned long flags, u8 clk_divider_flags, u8 shift, u8 width,
153 u8 frac_width, spinlock_t *lock)
154{
155 struct tegra_clk_frac_div *divider;
156 struct clk *clk;
157 struct clk_init_data init;
158
159 divider = kzalloc(sizeof(*divider), GFP_KERNEL);
160 if (!divider) {
161 pr_err("%s: could not allocate fractional divider clk\n",
162 __func__);
163 return ERR_PTR(-ENOMEM);
164 }
165
166 init.name = name;
167 init.ops = &tegra_clk_frac_div_ops;
168 init.flags = flags;
169 init.parent_names = parent_name ? &parent_name : NULL;
170 init.num_parents = parent_name ? 1 : 0;
171
172 divider->reg = reg;
173 divider->shift = shift;
174 divider->width = width;
175 divider->frac_width = frac_width;
176 divider->lock = lock;
177 divider->flags = clk_divider_flags;
178
179 /* Data in .init is copied by clk_register(), so stack variable OK */
180 divider->hw.init = &init;
181
182 clk = clk_register(NULL, &divider->hw);
183 if (IS_ERR(clk))
184 kfree(divider);
185
186 return clk;
187}
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c
new file mode 100644
index 000000000000..6dd533251e7b
--- /dev/null
+++ b/drivers/clk/tegra/clk-periph-gate.c
@@ -0,0 +1,179 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/clk.h>
18#include <linux/clk-provider.h>
19#include <linux/slab.h>
20#include <linux/io.h>
21#include <linux/delay.h>
22#include <linux/err.h>
23#include <linux/tegra-soc.h>
24
25#include "clk.h"
26
27static DEFINE_SPINLOCK(periph_ref_lock);
28
29/* Macros to assist peripheral gate clock */
30#define read_enb(gate) \
31 readl_relaxed(gate->clk_base + (gate->regs->enb_reg))
32#define write_enb_set(val, gate) \
33 writel_relaxed(val, gate->clk_base + (gate->regs->enb_set_reg))
34#define write_enb_clr(val, gate) \
35 writel_relaxed(val, gate->clk_base + (gate->regs->enb_clr_reg))
36
37#define read_rst(gate) \
38 readl_relaxed(gate->clk_base + (gate->regs->rst_reg))
39#define write_rst_set(val, gate) \
40 writel_relaxed(val, gate->clk_base + (gate->regs->rst_set_reg))
41#define write_rst_clr(val, gate) \
42 writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg))
43
44#define periph_clk_to_bit(periph) (1 << (gate->clk_num % 32))
45
46/* Peripheral gate clock ops */
47static int clk_periph_is_enabled(struct clk_hw *hw)
48{
49 struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
50 int state = 1;
51
52 if (!(read_enb(gate) & periph_clk_to_bit(gate)))
53 state = 0;
54
55 if (!(gate->flags & TEGRA_PERIPH_NO_RESET))
56 if (read_rst(gate) & periph_clk_to_bit(gate))
57 state = 0;
58
59 return state;
60}
61
62static int clk_periph_enable(struct clk_hw *hw)
63{
64 struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
65 unsigned long flags = 0;
66
67 spin_lock_irqsave(&periph_ref_lock, flags);
68
69 gate->enable_refcnt[gate->clk_num]++;
70 if (gate->enable_refcnt[gate->clk_num] > 1) {
71 spin_unlock_irqrestore(&periph_ref_lock, flags);
72 return 0;
73 }
74
75 write_enb_set(periph_clk_to_bit(gate), gate);
76 udelay(2);
77
78 if (!(gate->flags & TEGRA_PERIPH_NO_RESET) &&
79 !(gate->flags & TEGRA_PERIPH_MANUAL_RESET)) {
80 if (read_rst(gate) & periph_clk_to_bit(gate)) {
81 udelay(5); /* reset propogation delay */
82 write_rst_clr(periph_clk_to_bit(gate), gate);
83 }
84 }
85
86 spin_unlock_irqrestore(&periph_ref_lock, flags);
87
88 return 0;
89}
90
91static void clk_periph_disable(struct clk_hw *hw)
92{
93 struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
94 unsigned long flags = 0;
95
96 spin_lock_irqsave(&periph_ref_lock, flags);
97
98 gate->enable_refcnt[gate->clk_num]--;
99 if (gate->enable_refcnt[gate->clk_num] > 0) {
100 spin_unlock_irqrestore(&periph_ref_lock, flags);
101 return;
102 }
103
104 /*
105 * If peripheral is in the APB bus then read the APB bus to
106 * flush the write operation in apb bus. This will avoid the
107 * peripheral access after disabling clock
108 */
109 if (gate->flags & TEGRA_PERIPH_ON_APB)
110 tegra_read_chipid();
111
112 write_enb_clr(periph_clk_to_bit(gate), gate);
113
114 spin_unlock_irqrestore(&periph_ref_lock, flags);
115}
116
117void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert)
118{
119 if (gate->flags & TEGRA_PERIPH_NO_RESET)
120 return;
121
122 if (assert) {
123 /*
124 * If peripheral is in the APB bus then read the APB bus to
125 * flush the write operation in apb bus. This will avoid the
126 * peripheral access after disabling clock
127 */
128 if (gate->flags & TEGRA_PERIPH_ON_APB)
129 tegra_read_chipid();
130
131 write_rst_set(periph_clk_to_bit(gate), gate);
132 } else {
133 write_rst_clr(periph_clk_to_bit(gate), gate);
134 }
135}
136
137const struct clk_ops tegra_clk_periph_gate_ops = {
138 .is_enabled = clk_periph_is_enabled,
139 .enable = clk_periph_enable,
140 .disable = clk_periph_disable,
141};
142
143struct clk *tegra_clk_register_periph_gate(const char *name,
144 const char *parent_name, u8 gate_flags, void __iomem *clk_base,
145 unsigned long flags, int clk_num,
146 struct tegra_clk_periph_regs *pregs, int *enable_refcnt)
147{
148 struct tegra_clk_periph_gate *gate;
149 struct clk *clk;
150 struct clk_init_data init;
151
152 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
153 if (!gate) {
154 pr_err("%s: could not allocate periph gate clk\n", __func__);
155 return ERR_PTR(-ENOMEM);
156 }
157
158 init.name = name;
159 init.flags = flags;
160 init.parent_names = parent_name ? &parent_name : NULL;
161 init.num_parents = parent_name ? 1 : 0;
162 init.ops = &tegra_clk_periph_gate_ops;
163
164 gate->magic = TEGRA_CLK_PERIPH_GATE_MAGIC;
165 gate->clk_base = clk_base;
166 gate->clk_num = clk_num;
167 gate->flags = gate_flags;
168 gate->enable_refcnt = enable_refcnt;
169 gate->regs = pregs;
170
171 /* Data in .init is copied by clk_register(), so stack variable OK */
172 gate->hw.init = &init;
173
174 clk = clk_register(NULL, &gate->hw);
175 if (IS_ERR(clk))
176 kfree(gate);
177
178 return clk;
179}
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
new file mode 100644
index 000000000000..788486e6331a
--- /dev/null
+++ b/drivers/clk/tegra/clk-periph.c
@@ -0,0 +1,218 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/clk.h>
18#include <linux/clk-provider.h>
19#include <linux/slab.h>
20#include <linux/err.h>
21
22#include "clk.h"
23
24static u8 clk_periph_get_parent(struct clk_hw *hw)
25{
26 struct tegra_clk_periph *periph = to_clk_periph(hw);
27 const struct clk_ops *mux_ops = periph->mux_ops;
28 struct clk_hw *mux_hw = &periph->mux.hw;
29
30 mux_hw->clk = hw->clk;
31
32 return mux_ops->get_parent(mux_hw);
33}
34
35static int clk_periph_set_parent(struct clk_hw *hw, u8 index)
36{
37 struct tegra_clk_periph *periph = to_clk_periph(hw);
38 const struct clk_ops *mux_ops = periph->mux_ops;
39 struct clk_hw *mux_hw = &periph->mux.hw;
40
41 mux_hw->clk = hw->clk;
42
43 return mux_ops->set_parent(mux_hw, index);
44}
45
46static unsigned long clk_periph_recalc_rate(struct clk_hw *hw,
47 unsigned long parent_rate)
48{
49 struct tegra_clk_periph *periph = to_clk_periph(hw);
50 const struct clk_ops *div_ops = periph->div_ops;
51 struct clk_hw *div_hw = &periph->divider.hw;
52
53 div_hw->clk = hw->clk;
54
55 return div_ops->recalc_rate(div_hw, parent_rate);
56}
57
58static long clk_periph_round_rate(struct clk_hw *hw, unsigned long rate,
59 unsigned long *prate)
60{
61 struct tegra_clk_periph *periph = to_clk_periph(hw);
62 const struct clk_ops *div_ops = periph->div_ops;
63 struct clk_hw *div_hw = &periph->divider.hw;
64
65 div_hw->clk = hw->clk;
66
67 return div_ops->round_rate(div_hw, rate, prate);
68}
69
70static int clk_periph_set_rate(struct clk_hw *hw, unsigned long rate,
71 unsigned long parent_rate)
72{
73 struct tegra_clk_periph *periph = to_clk_periph(hw);
74 const struct clk_ops *div_ops = periph->div_ops;
75 struct clk_hw *div_hw = &periph->divider.hw;
76
77 div_hw->clk = hw->clk;
78
79 return div_ops->set_rate(div_hw, rate, parent_rate);
80}
81
82static int clk_periph_is_enabled(struct clk_hw *hw)
83{
84 struct tegra_clk_periph *periph = to_clk_periph(hw);
85 const struct clk_ops *gate_ops = periph->gate_ops;
86 struct clk_hw *gate_hw = &periph->gate.hw;
87
88 gate_hw->clk = hw->clk;
89
90 return gate_ops->is_enabled(gate_hw);
91}
92
93static int clk_periph_enable(struct clk_hw *hw)
94{
95 struct tegra_clk_periph *periph = to_clk_periph(hw);
96 const struct clk_ops *gate_ops = periph->gate_ops;
97 struct clk_hw *gate_hw = &periph->gate.hw;
98
99 gate_hw->clk = hw->clk;
100
101 return gate_ops->enable(gate_hw);
102}
103
104static void clk_periph_disable(struct clk_hw *hw)
105{
106 struct tegra_clk_periph *periph = to_clk_periph(hw);
107 const struct clk_ops *gate_ops = periph->gate_ops;
108 struct clk_hw *gate_hw = &periph->gate.hw;
109
110 gate_ops->disable(gate_hw);
111}
112
113void tegra_periph_reset_deassert(struct clk *c)
114{
115 struct clk_hw *hw = __clk_get_hw(c);
116 struct tegra_clk_periph *periph = to_clk_periph(hw);
117 struct tegra_clk_periph_gate *gate;
118
119 if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) {
120 gate = to_clk_periph_gate(hw);
121 if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) {
122 WARN_ON(1);
123 return;
124 }
125 } else {
126 gate = &periph->gate;
127 }
128
129 tegra_periph_reset(gate, 0);
130}
131
132void tegra_periph_reset_assert(struct clk *c)
133{
134 struct clk_hw *hw = __clk_get_hw(c);
135 struct tegra_clk_periph *periph = to_clk_periph(hw);
136 struct tegra_clk_periph_gate *gate;
137
138 if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) {
139 gate = to_clk_periph_gate(hw);
140 if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) {
141 WARN_ON(1);
142 return;
143 }
144 } else {
145 gate = &periph->gate;
146 }
147
148 tegra_periph_reset(gate, 1);
149}
150
151const struct clk_ops tegra_clk_periph_ops = {
152 .get_parent = clk_periph_get_parent,
153 .set_parent = clk_periph_set_parent,
154 .recalc_rate = clk_periph_recalc_rate,
155 .round_rate = clk_periph_round_rate,
156 .set_rate = clk_periph_set_rate,
157 .is_enabled = clk_periph_is_enabled,
158 .enable = clk_periph_enable,
159 .disable = clk_periph_disable,
160};
161
162const struct clk_ops tegra_clk_periph_nodiv_ops = {
163 .get_parent = clk_periph_get_parent,
164 .set_parent = clk_periph_set_parent,
165 .is_enabled = clk_periph_is_enabled,
166 .enable = clk_periph_enable,
167 .disable = clk_periph_disable,
168};
169
170static struct clk *_tegra_clk_register_periph(const char *name,
171 const char **parent_names, int num_parents,
172 struct tegra_clk_periph *periph,
173 void __iomem *clk_base, u32 offset, bool div)
174{
175 struct clk *clk;
176 struct clk_init_data init;
177
178 init.name = name;
179 init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops;
180 init.flags = div ? 0 : CLK_SET_RATE_PARENT;
181 init.parent_names = parent_names;
182 init.num_parents = num_parents;
183
184 /* Data in .init is copied by clk_register(), so stack variable OK */
185 periph->hw.init = &init;
186 periph->magic = TEGRA_CLK_PERIPH_MAGIC;
187 periph->mux.reg = clk_base + offset;
188 periph->divider.reg = div ? (clk_base + offset) : NULL;
189 periph->gate.clk_base = clk_base;
190
191 clk = clk_register(NULL, &periph->hw);
192 if (IS_ERR(clk))
193 return clk;
194
195 periph->mux.hw.clk = clk;
196 periph->divider.hw.clk = div ? clk : NULL;
197 periph->gate.hw.clk = clk;
198
199 return clk;
200}
201
202struct clk *tegra_clk_register_periph(const char *name,
203 const char **parent_names, int num_parents,
204 struct tegra_clk_periph *periph, void __iomem *clk_base,
205 u32 offset)
206{
207 return _tegra_clk_register_periph(name, parent_names, num_parents,
208 periph, clk_base, offset, true);
209}
210
211struct clk *tegra_clk_register_periph_nodiv(const char *name,
212 const char **parent_names, int num_parents,
213 struct tegra_clk_periph *periph, void __iomem *clk_base,
214 u32 offset)
215{
216 return _tegra_clk_register_periph(name, parent_names, num_parents,
217 periph, clk_base, offset, false);
218}
diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c
new file mode 100644
index 000000000000..3598987a451d
--- /dev/null
+++ b/drivers/clk/tegra/clk-pll-out.c
@@ -0,0 +1,123 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/kernel.h>
18#include <linux/io.h>
19#include <linux/err.h>
20#include <linux/delay.h>
21#include <linux/slab.h>
22#include <linux/clk-provider.h>
23#include <linux/clk.h>
24
25#include "clk.h"
26
27#define pll_out_enb(p) (BIT(p->enb_bit_idx))
28#define pll_out_rst(p) (BIT(p->rst_bit_idx))
29
30static int clk_pll_out_is_enabled(struct clk_hw *hw)
31{
32 struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
33 u32 val = readl_relaxed(pll_out->reg);
34 int state;
35
36 state = (val & pll_out_enb(pll_out)) ? 1 : 0;
37 if (!(val & (pll_out_rst(pll_out))))
38 state = 0;
39 return state;
40}
41
42static int clk_pll_out_enable(struct clk_hw *hw)
43{
44 struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
45 unsigned long flags = 0;
46 u32 val;
47
48 if (pll_out->lock)
49 spin_lock_irqsave(pll_out->lock, flags);
50
51 val = readl_relaxed(pll_out->reg);
52
53 val |= (pll_out_enb(pll_out) | pll_out_rst(pll_out));
54
55 writel_relaxed(val, pll_out->reg);
56 udelay(2);
57
58 if (pll_out->lock)
59 spin_unlock_irqrestore(pll_out->lock, flags);
60
61 return 0;
62}
63
64static void clk_pll_out_disable(struct clk_hw *hw)
65{
66 struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
67 unsigned long flags = 0;
68 u32 val;
69
70 if (pll_out->lock)
71 spin_lock_irqsave(pll_out->lock, flags);
72
73 val = readl_relaxed(pll_out->reg);
74
75 val &= ~(pll_out_enb(pll_out) | pll_out_rst(pll_out));
76
77 writel_relaxed(val, pll_out->reg);
78 udelay(2);
79
80 if (pll_out->lock)
81 spin_unlock_irqrestore(pll_out->lock, flags);
82}
83
84const struct clk_ops tegra_clk_pll_out_ops = {
85 .is_enabled = clk_pll_out_is_enabled,
86 .enable = clk_pll_out_enable,
87 .disable = clk_pll_out_disable,
88};
89
90struct clk *tegra_clk_register_pll_out(const char *name,
91 const char *parent_name, void __iomem *reg, u8 enb_bit_idx,
92 u8 rst_bit_idx, unsigned long flags, u8 pll_out_flags,
93 spinlock_t *lock)
94{
95 struct tegra_clk_pll_out *pll_out;
96 struct clk *clk;
97 struct clk_init_data init;
98
99 pll_out = kzalloc(sizeof(*pll_out), GFP_KERNEL);
100 if (!pll_out)
101 return ERR_PTR(-ENOMEM);
102
103 init.name = name;
104 init.ops = &tegra_clk_pll_out_ops;
105 init.parent_names = (parent_name ? &parent_name : NULL);
106 init.num_parents = (parent_name ? 1 : 0);
107 init.flags = flags;
108
109 pll_out->reg = reg;
110 pll_out->enb_bit_idx = enb_bit_idx;
111 pll_out->rst_bit_idx = rst_bit_idx;
112 pll_out->flags = pll_out_flags;
113 pll_out->lock = lock;
114
115 /* Data in .init is copied by clk_register(), so stack variable OK */
116 pll_out->hw.init = &init;
117
118 clk = clk_register(NULL, &pll_out->hw);
119 if (IS_ERR(clk))
120 kfree(pll_out);
121
122 return clk;
123}
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
new file mode 100644
index 000000000000..165f24734c1b
--- /dev/null
+++ b/drivers/clk/tegra/clk-pll.c
@@ -0,0 +1,648 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/slab.h>
18#include <linux/io.h>
19#include <linux/delay.h>
20#include <linux/err.h>
21#include <linux/clk-provider.h>
22#include <linux/clk.h>
23
24#include "clk.h"
25
26#define PLL_BASE_BYPASS BIT(31)
27#define PLL_BASE_ENABLE BIT(30)
28#define PLL_BASE_REF_ENABLE BIT(29)
29#define PLL_BASE_OVERRIDE BIT(28)
30
31#define PLL_BASE_DIVP_SHIFT 20
32#define PLL_BASE_DIVP_WIDTH 3
33#define PLL_BASE_DIVN_SHIFT 8
34#define PLL_BASE_DIVN_WIDTH 10
35#define PLL_BASE_DIVM_SHIFT 0
36#define PLL_BASE_DIVM_WIDTH 5
37#define PLLU_POST_DIVP_MASK 0x1
38
39#define PLL_MISC_DCCON_SHIFT 20
40#define PLL_MISC_CPCON_SHIFT 8
41#define PLL_MISC_CPCON_WIDTH 4
42#define PLL_MISC_CPCON_MASK ((1 << PLL_MISC_CPCON_WIDTH) - 1)
43#define PLL_MISC_LFCON_SHIFT 4
44#define PLL_MISC_LFCON_WIDTH 4
45#define PLL_MISC_LFCON_MASK ((1 << PLL_MISC_LFCON_WIDTH) - 1)
46#define PLL_MISC_VCOCON_SHIFT 0
47#define PLL_MISC_VCOCON_WIDTH 4
48#define PLL_MISC_VCOCON_MASK ((1 << PLL_MISC_VCOCON_WIDTH) - 1)
49
50#define OUT_OF_TABLE_CPCON 8
51
52#define PMC_PLLP_WB0_OVERRIDE 0xf8
53#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
54#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE BIT(11)
55
56#define PLL_POST_LOCK_DELAY 50
57
58#define PLLDU_LFCON_SET_DIVN 600
59
60#define PLLE_BASE_DIVCML_SHIFT 24
61#define PLLE_BASE_DIVCML_WIDTH 4
62#define PLLE_BASE_DIVP_SHIFT 16
63#define PLLE_BASE_DIVP_WIDTH 7
64#define PLLE_BASE_DIVN_SHIFT 8
65#define PLLE_BASE_DIVN_WIDTH 8
66#define PLLE_BASE_DIVM_SHIFT 0
67#define PLLE_BASE_DIVM_WIDTH 8
68
69#define PLLE_MISC_SETUP_BASE_SHIFT 16
70#define PLLE_MISC_SETUP_BASE_MASK (0xffff << PLLE_MISC_SETUP_BASE_SHIFT)
71#define PLLE_MISC_LOCK_ENABLE BIT(9)
72#define PLLE_MISC_READY BIT(15)
73#define PLLE_MISC_SETUP_EX_SHIFT 2
74#define PLLE_MISC_SETUP_EX_MASK (3 << PLLE_MISC_SETUP_EX_SHIFT)
75#define PLLE_MISC_SETUP_MASK (PLLE_MISC_SETUP_BASE_MASK | \
76 PLLE_MISC_SETUP_EX_MASK)
77#define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT)
78
79#define PLLE_SS_CTRL 0x68
80#define PLLE_SS_DISABLE (7 << 10)
81
82#define PMC_SATA_PWRGT 0x1ac
83#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
84#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
85
86#define pll_readl(offset, p) readl_relaxed(p->clk_base + offset)
87#define pll_readl_base(p) pll_readl(p->params->base_reg, p)
88#define pll_readl_misc(p) pll_readl(p->params->misc_reg, p)
89
90#define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset)
91#define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p)
92#define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p)
93
94#define mask(w) ((1 << (w)) - 1)
95#define divm_mask(p) mask(p->divm_width)
96#define divn_mask(p) mask(p->divn_width)
97#define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \
98 mask(p->divp_width))
99
100#define divm_max(p) (divm_mask(p))
101#define divn_max(p) (divn_mask(p))
102#define divp_max(p) (1 << (divp_mask(p)))
103
104static void clk_pll_enable_lock(struct tegra_clk_pll *pll)
105{
106 u32 val;
107
108 if (!(pll->flags & TEGRA_PLL_USE_LOCK))
109 return;
110
111 val = pll_readl_misc(pll);
112 val |= BIT(pll->params->lock_enable_bit_idx);
113 pll_writel_misc(val, pll);
114}
115
116static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll,
117 void __iomem *lock_addr, u32 lock_bit_idx)
118{
119 int i;
120 u32 val;
121
122 if (!(pll->flags & TEGRA_PLL_USE_LOCK)) {
123 udelay(pll->params->lock_delay);
124 return 0;
125 }
126
127 for (i = 0; i < pll->params->lock_delay; i++) {
128 val = readl_relaxed(lock_addr);
129 if (val & BIT(lock_bit_idx)) {
130 udelay(PLL_POST_LOCK_DELAY);
131 return 0;
132 }
133 udelay(2); /* timeout = 2 * lock time */
134 }
135
136 pr_err("%s: Timed out waiting for pll %s lock\n", __func__,
137 __clk_get_name(pll->hw.clk));
138
139 return -1;
140}
141
142static int clk_pll_is_enabled(struct clk_hw *hw)
143{
144 struct tegra_clk_pll *pll = to_clk_pll(hw);
145 u32 val;
146
147 if (pll->flags & TEGRA_PLLM) {
148 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
149 if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)
150 return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0;
151 }
152
153 val = pll_readl_base(pll);
154
155 return val & PLL_BASE_ENABLE ? 1 : 0;
156}
157
158static int _clk_pll_enable(struct clk_hw *hw)
159{
160 struct tegra_clk_pll *pll = to_clk_pll(hw);
161 u32 val;
162
163 clk_pll_enable_lock(pll);
164
165 val = pll_readl_base(pll);
166 val &= ~PLL_BASE_BYPASS;
167 val |= PLL_BASE_ENABLE;
168 pll_writel_base(val, pll);
169
170 if (pll->flags & TEGRA_PLLM) {
171 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
172 val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
173 writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
174 }
175
176 clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg,
177 pll->params->lock_bit_idx);
178
179 return 0;
180}
181
182static void _clk_pll_disable(struct clk_hw *hw)
183{
184 struct tegra_clk_pll *pll = to_clk_pll(hw);
185 u32 val;
186
187 val = pll_readl_base(pll);
188 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
189 pll_writel_base(val, pll);
190
191 if (pll->flags & TEGRA_PLLM) {
192 val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
193 val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
194 writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
195 }
196}
197
198static int clk_pll_enable(struct clk_hw *hw)
199{
200 struct tegra_clk_pll *pll = to_clk_pll(hw);
201 unsigned long flags = 0;
202 int ret;
203
204 if (pll->lock)
205 spin_lock_irqsave(pll->lock, flags);
206
207 ret = _clk_pll_enable(hw);
208
209 if (pll->lock)
210 spin_unlock_irqrestore(pll->lock, flags);
211
212 return ret;
213}
214
215static void clk_pll_disable(struct clk_hw *hw)
216{
217 struct tegra_clk_pll *pll = to_clk_pll(hw);
218 unsigned long flags = 0;
219
220 if (pll->lock)
221 spin_lock_irqsave(pll->lock, flags);
222
223 _clk_pll_disable(hw);
224
225 if (pll->lock)
226 spin_unlock_irqrestore(pll->lock, flags);
227}
228
229static int _get_table_rate(struct clk_hw *hw,
230 struct tegra_clk_pll_freq_table *cfg,
231 unsigned long rate, unsigned long parent_rate)
232{
233 struct tegra_clk_pll *pll = to_clk_pll(hw);
234 struct tegra_clk_pll_freq_table *sel;
235
236 for (sel = pll->freq_table; sel->input_rate != 0; sel++)
237 if (sel->input_rate == parent_rate &&
238 sel->output_rate == rate)
239 break;
240
241 if (sel->input_rate == 0)
242 return -EINVAL;
243
244 BUG_ON(sel->p < 1);
245
246 cfg->input_rate = sel->input_rate;
247 cfg->output_rate = sel->output_rate;
248 cfg->m = sel->m;
249 cfg->n = sel->n;
250 cfg->p = sel->p;
251 cfg->cpcon = sel->cpcon;
252
253 return 0;
254}
255
256static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
257 unsigned long rate, unsigned long parent_rate)
258{
259 struct tegra_clk_pll *pll = to_clk_pll(hw);
260 unsigned long cfreq;
261 u32 p_div = 0;
262
263 switch (parent_rate) {
264 case 12000000:
265 case 26000000:
266 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
267 break;
268 case 13000000:
269 cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
270 break;
271 case 16800000:
272 case 19200000:
273 cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
274 break;
275 case 9600000:
276 case 28800000:
277 /*
278 * PLL_P_OUT1 rate is not listed in PLLA table
279 */
280 cfreq = parent_rate/(parent_rate/1000000);
281 break;
282 default:
283 pr_err("%s Unexpected reference rate %lu\n",
284 __func__, parent_rate);
285 BUG();
286 }
287
288 /* Raise VCO to guarantee 0.5% accuracy */
289 for (cfg->output_rate = rate; cfg->output_rate < 200 * cfreq;
290 cfg->output_rate <<= 1)
291 p_div++;
292
293 cfg->p = 1 << p_div;
294 cfg->m = parent_rate / cfreq;
295 cfg->n = cfg->output_rate / cfreq;
296 cfg->cpcon = OUT_OF_TABLE_CPCON;
297
298 if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) ||
299 cfg->p > divp_max(pll) || cfg->output_rate > pll->params->vco_max) {
300 pr_err("%s: Failed to set %s rate %lu\n",
301 __func__, __clk_get_name(hw->clk), rate);
302 return -EINVAL;
303 }
304
305 return 0;
306}
307
308static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
309 unsigned long rate)
310{
311 struct tegra_clk_pll *pll = to_clk_pll(hw);
312 unsigned long flags = 0;
313 u32 divp, val, old_base;
314 int state;
315
316 divp = __ffs(cfg->p);
317
318 if (pll->flags & TEGRA_PLLU)
319 divp ^= 1;
320
321 if (pll->lock)
322 spin_lock_irqsave(pll->lock, flags);
323
324 old_base = val = pll_readl_base(pll);
325 val &= ~((divm_mask(pll) << pll->divm_shift) |
326 (divn_mask(pll) << pll->divn_shift) |
327 (divp_mask(pll) << pll->divp_shift));
328 val |= ((cfg->m << pll->divm_shift) |
329 (cfg->n << pll->divn_shift) |
330 (divp << pll->divp_shift));
331 if (val == old_base) {
332 if (pll->lock)
333 spin_unlock_irqrestore(pll->lock, flags);
334 return 0;
335 }
336
337 state = clk_pll_is_enabled(hw);
338
339 if (state) {
340 _clk_pll_disable(hw);
341 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
342 }
343 pll_writel_base(val, pll);
344
345 if (pll->flags & TEGRA_PLL_HAS_CPCON) {
346 val = pll_readl_misc(pll);
347 val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT);
348 val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT;
349 if (pll->flags & TEGRA_PLL_SET_LFCON) {
350 val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT);
351 if (cfg->n >= PLLDU_LFCON_SET_DIVN)
352 val |= 0x1 << PLL_MISC_LFCON_SHIFT;
353 } else if (pll->flags & TEGRA_PLL_SET_DCCON) {
354 val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
355 if (rate >= (pll->params->vco_max >> 1))
356 val |= 0x1 << PLL_MISC_DCCON_SHIFT;
357 }
358 pll_writel_misc(val, pll);
359 }
360
361 if (pll->lock)
362 spin_unlock_irqrestore(pll->lock, flags);
363
364 if (state)
365 clk_pll_enable(hw);
366
367 return 0;
368}
369
370static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
371 unsigned long parent_rate)
372{
373 struct tegra_clk_pll *pll = to_clk_pll(hw);
374 struct tegra_clk_pll_freq_table cfg;
375
376 if (pll->flags & TEGRA_PLL_FIXED) {
377 if (rate != pll->fixed_rate) {
378 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
379 __func__, __clk_get_name(hw->clk),
380 pll->fixed_rate, rate);
381 return -EINVAL;
382 }
383 return 0;
384 }
385
386 if (_get_table_rate(hw, &cfg, rate, parent_rate) &&
387 _calc_rate(hw, &cfg, rate, parent_rate))
388 return -EINVAL;
389
390 return _program_pll(hw, &cfg, rate);
391}
392
393static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
394 unsigned long *prate)
395{
396 struct tegra_clk_pll *pll = to_clk_pll(hw);
397 struct tegra_clk_pll_freq_table cfg;
398 u64 output_rate = *prate;
399
400 if (pll->flags & TEGRA_PLL_FIXED)
401 return pll->fixed_rate;
402
403 /* PLLM is used for memory; we do not change rate */
404 if (pll->flags & TEGRA_PLLM)
405 return __clk_get_rate(hw->clk);
406
407 if (_get_table_rate(hw, &cfg, rate, *prate) &&
408 _calc_rate(hw, &cfg, rate, *prate))
409 return -EINVAL;
410
411 output_rate *= cfg.n;
412 do_div(output_rate, cfg.m * cfg.p);
413
414 return output_rate;
415}
416
417static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
418 unsigned long parent_rate)
419{
420 struct tegra_clk_pll *pll = to_clk_pll(hw);
421 u32 val = pll_readl_base(pll);
422 u32 divn = 0, divm = 0, divp = 0;
423 u64 rate = parent_rate;
424
425 if (val & PLL_BASE_BYPASS)
426 return parent_rate;
427
428 if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) {
429 struct tegra_clk_pll_freq_table sel;
430 if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) {
431 pr_err("Clock %s has unknown fixed frequency\n",
432 __clk_get_name(hw->clk));
433 BUG();
434 }
435 return pll->fixed_rate;
436 }
437
438 divp = (val >> pll->divp_shift) & (divp_mask(pll));
439 if (pll->flags & TEGRA_PLLU)
440 divp ^= 1;
441
442 divn = (val >> pll->divn_shift) & (divn_mask(pll));
443 divm = (val >> pll->divm_shift) & (divm_mask(pll));
444 divm *= (1 << divp);
445
446 rate *= divn;
447 do_div(rate, divm);
448 return rate;
449}
450
451static int clk_plle_training(struct tegra_clk_pll *pll)
452{
453 u32 val;
454 unsigned long timeout;
455
456 if (!pll->pmc)
457 return -ENOSYS;
458
459 /*
460 * PLLE is already disabled, and setup cleared;
461 * create falling edge on PLLE IDDQ input.
462 */
463 val = readl(pll->pmc + PMC_SATA_PWRGT);
464 val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
465 writel(val, pll->pmc + PMC_SATA_PWRGT);
466
467 val = readl(pll->pmc + PMC_SATA_PWRGT);
468 val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
469 writel(val, pll->pmc + PMC_SATA_PWRGT);
470
471 val = readl(pll->pmc + PMC_SATA_PWRGT);
472 val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
473 writel(val, pll->pmc + PMC_SATA_PWRGT);
474
475 val = pll_readl_misc(pll);
476
477 timeout = jiffies + msecs_to_jiffies(100);
478 while (1) {
479 val = pll_readl_misc(pll);
480 if (val & PLLE_MISC_READY)
481 break;
482 if (time_after(jiffies, timeout)) {
483 pr_err("%s: timeout waiting for PLLE\n", __func__);
484 return -EBUSY;
485 }
486 udelay(300);
487 }
488
489 return 0;
490}
491
492static int clk_plle_enable(struct clk_hw *hw)
493{
494 struct tegra_clk_pll *pll = to_clk_pll(hw);
495 unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk));
496 struct tegra_clk_pll_freq_table sel;
497 u32 val;
498 int err;
499
500 if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
501 return -EINVAL;
502
503 clk_pll_disable(hw);
504
505 val = pll_readl_misc(pll);
506 val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
507 pll_writel_misc(val, pll);
508
509 val = pll_readl_misc(pll);
510 if (!(val & PLLE_MISC_READY)) {
511 err = clk_plle_training(pll);
512 if (err)
513 return err;
514 }
515
516 if (pll->flags & TEGRA_PLLE_CONFIGURE) {
517 /* configure dividers */
518 val = pll_readl_base(pll);
519 val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
520 val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
521 val |= sel.m << pll->divm_shift;
522 val |= sel.n << pll->divn_shift;
523 val |= sel.p << pll->divp_shift;
524 val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
525 pll_writel_base(val, pll);
526 }
527
528 val = pll_readl_misc(pll);
529 val |= PLLE_MISC_SETUP_VALUE;
530 val |= PLLE_MISC_LOCK_ENABLE;
531 pll_writel_misc(val, pll);
532
533 val = readl(pll->clk_base + PLLE_SS_CTRL);
534 val |= PLLE_SS_DISABLE;
535 writel(val, pll->clk_base + PLLE_SS_CTRL);
536
537 val |= pll_readl_base(pll);
538 val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
539 pll_writel_base(val, pll);
540
541 clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->misc_reg,
542 pll->params->lock_bit_idx);
543 return 0;
544}
545
546static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
547 unsigned long parent_rate)
548{
549 struct tegra_clk_pll *pll = to_clk_pll(hw);
550 u32 val = pll_readl_base(pll);
551 u32 divn = 0, divm = 0, divp = 0;
552 u64 rate = parent_rate;
553
554 divp = (val >> pll->divp_shift) & (divp_mask(pll));
555 divn = (val >> pll->divn_shift) & (divn_mask(pll));
556 divm = (val >> pll->divm_shift) & (divm_mask(pll));
557 divm *= divp;
558
559 rate *= divn;
560 do_div(rate, divm);
561 return rate;
562}
563
564const struct clk_ops tegra_clk_pll_ops = {
565 .is_enabled = clk_pll_is_enabled,
566 .enable = clk_pll_enable,
567 .disable = clk_pll_disable,
568 .recalc_rate = clk_pll_recalc_rate,
569 .round_rate = clk_pll_round_rate,
570 .set_rate = clk_pll_set_rate,
571};
572
573const struct clk_ops tegra_clk_plle_ops = {
574 .recalc_rate = clk_plle_recalc_rate,
575 .is_enabled = clk_pll_is_enabled,
576 .disable = clk_pll_disable,
577 .enable = clk_plle_enable,
578};
579
580static struct clk *_tegra_clk_register_pll(const char *name,
581 const char *parent_name, void __iomem *clk_base,
582 void __iomem *pmc, unsigned long flags,
583 unsigned long fixed_rate,
584 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
585 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock,
586 const struct clk_ops *ops)
587{
588 struct tegra_clk_pll *pll;
589 struct clk *clk;
590 struct clk_init_data init;
591
592 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
593 if (!pll)
594 return ERR_PTR(-ENOMEM);
595
596 init.name = name;
597 init.ops = ops;
598 init.flags = flags;
599 init.parent_names = (parent_name ? &parent_name : NULL);
600 init.num_parents = (parent_name ? 1 : 0);
601
602 pll->clk_base = clk_base;
603 pll->pmc = pmc;
604
605 pll->freq_table = freq_table;
606 pll->params = pll_params;
607 pll->fixed_rate = fixed_rate;
608 pll->flags = pll_flags;
609 pll->lock = lock;
610
611 pll->divp_shift = PLL_BASE_DIVP_SHIFT;
612 pll->divp_width = PLL_BASE_DIVP_WIDTH;
613 pll->divn_shift = PLL_BASE_DIVN_SHIFT;
614 pll->divn_width = PLL_BASE_DIVN_WIDTH;
615 pll->divm_shift = PLL_BASE_DIVM_SHIFT;
616 pll->divm_width = PLL_BASE_DIVM_WIDTH;
617
618 /* Data in .init is copied by clk_register(), so stack variable OK */
619 pll->hw.init = &init;
620
621 clk = clk_register(NULL, &pll->hw);
622 if (IS_ERR(clk))
623 kfree(pll);
624
625 return clk;
626}
627
628struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
629 void __iomem *clk_base, void __iomem *pmc,
630 unsigned long flags, unsigned long fixed_rate,
631 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
632 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
633{
634 return _tegra_clk_register_pll(name, parent_name, clk_base, pmc,
635 flags, fixed_rate, pll_params, pll_flags, freq_table,
636 lock, &tegra_clk_pll_ops);
637}
638
639struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
640 void __iomem *clk_base, void __iomem *pmc,
641 unsigned long flags, unsigned long fixed_rate,
642 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
643 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
644{
645 return _tegra_clk_register_pll(name, parent_name, clk_base, pmc,
646 flags, fixed_rate, pll_params, pll_flags, freq_table,
647 lock, &tegra_clk_plle_ops);
648}
diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
new file mode 100644
index 000000000000..7ad48a832334
--- /dev/null
+++ b/drivers/clk/tegra/clk-super.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/kernel.h>
18#include <linux/io.h>
19#include <linux/delay.h>
20#include <linux/err.h>
21#include <linux/slab.h>
22#include <linux/clk-provider.h>
23#include <linux/clk.h>
24
25#include "clk.h"
26
27#define SUPER_STATE_IDLE 0
28#define SUPER_STATE_RUN 1
29#define SUPER_STATE_IRQ 2
30#define SUPER_STATE_FIQ 3
31
32#define SUPER_STATE_SHIFT 28
33#define SUPER_STATE_MASK ((BIT(SUPER_STATE_IDLE) | BIT(SUPER_STATE_RUN) | \
34 BIT(SUPER_STATE_IRQ) | BIT(SUPER_STATE_FIQ)) \
35 << SUPER_STATE_SHIFT)
36
37#define SUPER_LP_DIV2_BYPASS (1 << 16)
38
39#define super_state(s) (BIT(s) << SUPER_STATE_SHIFT)
40#define super_state_to_src_shift(m, s) ((m->width * s))
41#define super_state_to_src_mask(m) (((1 << m->width) - 1))
42
43static u8 clk_super_get_parent(struct clk_hw *hw)
44{
45 struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
46 u32 val, state;
47 u8 source, shift;
48
49 val = readl_relaxed(mux->reg);
50
51 state = val & SUPER_STATE_MASK;
52
53 BUG_ON((state != super_state(SUPER_STATE_RUN)) &&
54 (state != super_state(SUPER_STATE_IDLE)));
55 shift = (state == super_state(SUPER_STATE_IDLE)) ?
56 super_state_to_src_shift(mux, SUPER_STATE_IDLE) :
57 super_state_to_src_shift(mux, SUPER_STATE_RUN);
58
59 source = (val >> shift) & super_state_to_src_mask(mux);
60
61 /*
62 * If LP_DIV2_BYPASS is not set and PLLX is current parent then
63 * PLLX/2 is the input source to CCLKLP.
64 */
65 if ((mux->flags & TEGRA_DIVIDER_2) && !(val & SUPER_LP_DIV2_BYPASS) &&
66 (source == mux->pllx_index))
67 source = mux->div2_index;
68
69 return source;
70}
71
72static int clk_super_set_parent(struct clk_hw *hw, u8 index)
73{
74 struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
75 u32 val, state;
76 u8 parent_index, shift;
77
78 val = readl_relaxed(mux->reg);
79 state = val & SUPER_STATE_MASK;
80 BUG_ON((state != super_state(SUPER_STATE_RUN)) &&
81 (state != super_state(SUPER_STATE_IDLE)));
82 shift = (state == super_state(SUPER_STATE_IDLE)) ?
83 super_state_to_src_shift(mux, SUPER_STATE_IDLE) :
84 super_state_to_src_shift(mux, SUPER_STATE_RUN);
85
86 /*
87 * For LP mode super-clock switch between PLLX direct
88 * and divided-by-2 outputs is allowed only when other
89 * than PLLX clock source is current parent.
90 */
91 if ((mux->flags & TEGRA_DIVIDER_2) && ((index == mux->div2_index) ||
92 (index == mux->pllx_index))) {
93 parent_index = clk_super_get_parent(hw);
94 if ((parent_index == mux->div2_index) ||
95 (parent_index == mux->pllx_index))
96 return -EINVAL;
97
98 val ^= SUPER_LP_DIV2_BYPASS;
99 writel_relaxed(val, mux->reg);
100 udelay(2);
101
102 if (index == mux->div2_index)
103 index = mux->pllx_index;
104 }
105 val &= ~((super_state_to_src_mask(mux)) << shift);
106 val |= (index & (super_state_to_src_mask(mux))) << shift;
107
108 writel_relaxed(val, mux->reg);
109 udelay(2);
110 return 0;
111}
112
113const struct clk_ops tegra_clk_super_ops = {
114 .get_parent = clk_super_get_parent,
115 .set_parent = clk_super_set_parent,
116};
117
118struct clk *tegra_clk_register_super_mux(const char *name,
119 const char **parent_names, u8 num_parents,
120 unsigned long flags, void __iomem *reg, u8 clk_super_flags,
121 u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock)
122{
123 struct tegra_clk_super_mux *super;
124 struct clk *clk;
125 struct clk_init_data init;
126
127 super = kzalloc(sizeof(*super), GFP_KERNEL);
128 if (!super) {
129 pr_err("%s: could not allocate super clk\n", __func__);
130 return ERR_PTR(-ENOMEM);
131 }
132
133 init.name = name;
134 init.ops = &tegra_clk_super_ops;
135 init.flags = flags;
136 init.parent_names = parent_names;
137 init.num_parents = num_parents;
138
139 super->reg = reg;
140 super->pllx_index = pllx_index;
141 super->div2_index = div2_index;
142 super->lock = lock;
143 super->width = width;
144 super->flags = clk_super_flags;
145
146 /* Data in .init is copied by clk_register(), so stack variable OK */
147 super->hw.init = &init;
148
149 clk = clk_register(NULL, &super->hw);
150 if (IS_ERR(clk))
151 kfree(super);
152
153 return clk;
154}
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
new file mode 100644
index 000000000000..5d41569883a7
--- /dev/null
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -0,0 +1,1349 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/io.h>
18#include <linux/clk.h>
19#include <linux/clk-provider.h>
20#include <linux/clkdev.h>
21#include <linux/of.h>
22#include <linux/of_address.h>
23#include <linux/clk/tegra.h>
24#include <linux/delay.h>
25
26#include "clk.h"
27
28#define RST_DEVICES_L 0x004
29#define RST_DEVICES_H 0x008
30#define RST_DEVICES_U 0x00c
31#define RST_DEVICES_SET_L 0x300
32#define RST_DEVICES_CLR_L 0x304
33#define RST_DEVICES_SET_H 0x308
34#define RST_DEVICES_CLR_H 0x30c
35#define RST_DEVICES_SET_U 0x310
36#define RST_DEVICES_CLR_U 0x314
37#define RST_DEVICES_NUM 3
38
39#define CLK_OUT_ENB_L 0x010
40#define CLK_OUT_ENB_H 0x014
41#define CLK_OUT_ENB_U 0x018
42#define CLK_OUT_ENB_SET_L 0x320
43#define CLK_OUT_ENB_CLR_L 0x324
44#define CLK_OUT_ENB_SET_H 0x328
45#define CLK_OUT_ENB_CLR_H 0x32c
46#define CLK_OUT_ENB_SET_U 0x330
47#define CLK_OUT_ENB_CLR_U 0x334
48#define CLK_OUT_ENB_NUM 3
49
50#define OSC_CTRL 0x50
51#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
52#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
53#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
54#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
55#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
56#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
57
58#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28)
59#define OSC_CTRL_PLL_REF_DIV_1 (0<<28)
60#define OSC_CTRL_PLL_REF_DIV_2 (1<<28)
61#define OSC_CTRL_PLL_REF_DIV_4 (2<<28)
62
63#define OSC_FREQ_DET 0x58
64#define OSC_FREQ_DET_TRIG (1<<31)
65
66#define OSC_FREQ_DET_STATUS 0x5c
67#define OSC_FREQ_DET_BUSY (1<<31)
68#define OSC_FREQ_DET_CNT_MASK 0xFFFF
69
70#define PLLS_BASE 0xf0
71#define PLLS_MISC 0xf4
72#define PLLC_BASE 0x80
73#define PLLC_MISC 0x8c
74#define PLLM_BASE 0x90
75#define PLLM_MISC 0x9c
76#define PLLP_BASE 0xa0
77#define PLLP_MISC 0xac
78#define PLLA_BASE 0xb0
79#define PLLA_MISC 0xbc
80#define PLLU_BASE 0xc0
81#define PLLU_MISC 0xcc
82#define PLLD_BASE 0xd0
83#define PLLD_MISC 0xdc
84#define PLLX_BASE 0xe0
85#define PLLX_MISC 0xe4
86#define PLLE_BASE 0xe8
87#define PLLE_MISC 0xec
88
89#define PLL_BASE_LOCK 27
90#define PLLE_MISC_LOCK 11
91
92#define PLL_MISC_LOCK_ENABLE 18
93#define PLLDU_MISC_LOCK_ENABLE 22
94#define PLLE_MISC_LOCK_ENABLE 9
95
96#define PLLC_OUT 0x84
97#define PLLM_OUT 0x94
98#define PLLP_OUTA 0xa4
99#define PLLP_OUTB 0xa8
100#define PLLA_OUT 0xb4
101
102#define CCLK_BURST_POLICY 0x20
103#define SUPER_CCLK_DIVIDER 0x24
104#define SCLK_BURST_POLICY 0x28
105#define SUPER_SCLK_DIVIDER 0x2c
106#define CLK_SYSTEM_RATE 0x30
107
108#define CCLK_BURST_POLICY_SHIFT 28
109#define CCLK_RUN_POLICY_SHIFT 4
110#define CCLK_IDLE_POLICY_SHIFT 0
111#define CCLK_IDLE_POLICY 1
112#define CCLK_RUN_POLICY 2
113#define CCLK_BURST_POLICY_PLLX 8
114
115#define CLK_SOURCE_I2S1 0x100
116#define CLK_SOURCE_I2S2 0x104
117#define CLK_SOURCE_SPDIF_OUT 0x108
118#define CLK_SOURCE_SPDIF_IN 0x10c
119#define CLK_SOURCE_PWM 0x110
120#define CLK_SOURCE_SPI 0x114
121#define CLK_SOURCE_SBC1 0x134
122#define CLK_SOURCE_SBC2 0x118
123#define CLK_SOURCE_SBC3 0x11c
124#define CLK_SOURCE_SBC4 0x1b4
125#define CLK_SOURCE_XIO 0x120
126#define CLK_SOURCE_TWC 0x12c
127#define CLK_SOURCE_IDE 0x144
128#define CLK_SOURCE_NDFLASH 0x160
129#define CLK_SOURCE_VFIR 0x168
130#define CLK_SOURCE_SDMMC1 0x150
131#define CLK_SOURCE_SDMMC2 0x154
132#define CLK_SOURCE_SDMMC3 0x1bc
133#define CLK_SOURCE_SDMMC4 0x164
134#define CLK_SOURCE_CVE 0x140
135#define CLK_SOURCE_TVO 0x188
136#define CLK_SOURCE_TVDAC 0x194
137#define CLK_SOURCE_HDMI 0x18c
138#define CLK_SOURCE_DISP1 0x138
139#define CLK_SOURCE_DISP2 0x13c
140#define CLK_SOURCE_CSITE 0x1d4
141#define CLK_SOURCE_LA 0x1f8
142#define CLK_SOURCE_OWR 0x1cc
143#define CLK_SOURCE_NOR 0x1d0
144#define CLK_SOURCE_MIPI 0x174
145#define CLK_SOURCE_I2C1 0x124
146#define CLK_SOURCE_I2C2 0x198
147#define CLK_SOURCE_I2C3 0x1b8
148#define CLK_SOURCE_DVC 0x128
149#define CLK_SOURCE_UARTA 0x178
150#define CLK_SOURCE_UARTB 0x17c
151#define CLK_SOURCE_UARTC 0x1a0
152#define CLK_SOURCE_UARTD 0x1c0
153#define CLK_SOURCE_UARTE 0x1c4
154#define CLK_SOURCE_3D 0x158
155#define CLK_SOURCE_2D 0x15c
156#define CLK_SOURCE_MPE 0x170
157#define CLK_SOURCE_EPP 0x16c
158#define CLK_SOURCE_HOST1X 0x180
159#define CLK_SOURCE_VDE 0x1c8
160#define CLK_SOURCE_VI 0x148
161#define CLK_SOURCE_VI_SENSOR 0x1a8
162#define CLK_SOURCE_EMC 0x19c
163
164#define AUDIO_SYNC_CLK 0x38
165
166#define PMC_CTRL 0x0
167#define PMC_CTRL_BLINK_ENB 7
168#define PMC_DPD_PADS_ORIDE 0x1c
169#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20
170#define PMC_BLINK_TIMER 0x40
171
172/* Tegra CPU clock and reset control regs */
173#define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c
174#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340
175#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344
176
177#define CPU_CLOCK(cpu) (0x1 << (8 + cpu))
178#define CPU_RESET(cpu) (0x1111ul << (cpu))
179
180#ifdef CONFIG_PM_SLEEP
181static struct cpu_clk_suspend_context {
182 u32 pllx_misc;
183 u32 pllx_base;
184
185 u32 cpu_burst;
186 u32 clk_csite_src;
187 u32 cclk_divider;
188} tegra20_cpu_clk_sctx;
189#endif
190
191static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
192
193static void __iomem *clk_base;
194static void __iomem *pmc_base;
195
196static DEFINE_SPINLOCK(pll_div_lock);
197
198#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \
199 _clk_num, _regs, _gate_flags, _clk_id) \
200 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
201 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \
202 _regs, _clk_num, periph_clk_enb_refcnt, \
203 _gate_flags, _clk_id)
204
205#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \
206 _clk_num, _regs, _gate_flags, _clk_id) \
207 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
208 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \
209 _clk_num, periph_clk_enb_refcnt, _gate_flags, \
210 _clk_id)
211
212#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
213 _clk_num, _regs, _gate_flags, _clk_id) \
214 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
215 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, _regs, \
216 _clk_num, periph_clk_enb_refcnt, _gate_flags, \
217 _clk_id)
218
219#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
220 _mux_shift, _mux_width, _clk_num, _regs, \
221 _gate_flags, _clk_id) \
222 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
223 _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \
224 _clk_num, periph_clk_enb_refcnt, _gate_flags, \
225 _clk_id)
226
227/* IDs assigned here must be in sync with DT bindings definition
228 * for Tegra20 clocks .
229 */
230enum tegra20_clk {
231 cpu, ac97 = 3, rtc, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1,
232 ndflash, sdmmc1, sdmmc4, twc, pwm, i2s2, epp, gr2d = 21, usbd, isp,
233 gr3d, ide, disp2, disp1, host1x, vcp, cache2 = 31, mem, ahbdma, apbdma,
234 kbc = 36, stat_mon, pmc, fuse, kfuse, sbc1, nor, spi, sbc2, xio, sbc3,
235 dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2,
236 usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3,
237 pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb,
238 iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev1, cdev2,
239 uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve,
240 osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0,
241 pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1,
242 pll_p, pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_u,
243 pll_x, audio, pll_ref, twd, clk_max,
244};
245
246static struct clk *clks[clk_max];
247static struct clk_onecell_data clk_data;
248
249static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
250 { 12000000, 600000000, 600, 12, 1, 8 },
251 { 13000000, 600000000, 600, 13, 1, 8 },
252 { 19200000, 600000000, 500, 16, 1, 6 },
253 { 26000000, 600000000, 600, 26, 1, 8 },
254 { 0, 0, 0, 0, 0, 0 },
255};
256
257static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
258 { 12000000, 666000000, 666, 12, 1, 8},
259 { 13000000, 666000000, 666, 13, 1, 8},
260 { 19200000, 666000000, 555, 16, 1, 8},
261 { 26000000, 666000000, 666, 26, 1, 8},
262 { 12000000, 600000000, 600, 12, 1, 8},
263 { 13000000, 600000000, 600, 13, 1, 8},
264 { 19200000, 600000000, 375, 12, 1, 6},
265 { 26000000, 600000000, 600, 26, 1, 8},
266 { 0, 0, 0, 0, 0, 0 },
267};
268
269static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
270 { 12000000, 216000000, 432, 12, 2, 8},
271 { 13000000, 216000000, 432, 13, 2, 8},
272 { 19200000, 216000000, 90, 4, 2, 1},
273 { 26000000, 216000000, 432, 26, 2, 8},
274 { 12000000, 432000000, 432, 12, 1, 8},
275 { 13000000, 432000000, 432, 13, 1, 8},
276 { 19200000, 432000000, 90, 4, 1, 1},
277 { 26000000, 432000000, 432, 26, 1, 8},
278 { 0, 0, 0, 0, 0, 0 },
279};
280
281static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
282 { 28800000, 56448000, 49, 25, 1, 1},
283 { 28800000, 73728000, 64, 25, 1, 1},
284 { 28800000, 24000000, 5, 6, 1, 1},
285 { 0, 0, 0, 0, 0, 0 },
286};
287
288static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
289 { 12000000, 216000000, 216, 12, 1, 4},
290 { 13000000, 216000000, 216, 13, 1, 4},
291 { 19200000, 216000000, 135, 12, 1, 3},
292 { 26000000, 216000000, 216, 26, 1, 4},
293
294 { 12000000, 594000000, 594, 12, 1, 8},
295 { 13000000, 594000000, 594, 13, 1, 8},
296 { 19200000, 594000000, 495, 16, 1, 8},
297 { 26000000, 594000000, 594, 26, 1, 8},
298
299 { 12000000, 1000000000, 1000, 12, 1, 12},
300 { 13000000, 1000000000, 1000, 13, 1, 12},
301 { 19200000, 1000000000, 625, 12, 1, 8},
302 { 26000000, 1000000000, 1000, 26, 1, 12},
303
304 { 0, 0, 0, 0, 0, 0 },
305};
306
307static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
308 { 12000000, 480000000, 960, 12, 2, 0},
309 { 13000000, 480000000, 960, 13, 2, 0},
310 { 19200000, 480000000, 200, 4, 2, 0},
311 { 26000000, 480000000, 960, 26, 2, 0},
312 { 0, 0, 0, 0, 0, 0 },
313};
314
315static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
316 /* 1 GHz */
317 { 12000000, 1000000000, 1000, 12, 1, 12},
318 { 13000000, 1000000000, 1000, 13, 1, 12},
319 { 19200000, 1000000000, 625, 12, 1, 8},
320 { 26000000, 1000000000, 1000, 26, 1, 12},
321
322 /* 912 MHz */
323 { 12000000, 912000000, 912, 12, 1, 12},
324 { 13000000, 912000000, 912, 13, 1, 12},
325 { 19200000, 912000000, 760, 16, 1, 8},
326 { 26000000, 912000000, 912, 26, 1, 12},
327
328 /* 816 MHz */
329 { 12000000, 816000000, 816, 12, 1, 12},
330 { 13000000, 816000000, 816, 13, 1, 12},
331 { 19200000, 816000000, 680, 16, 1, 8},
332 { 26000000, 816000000, 816, 26, 1, 12},
333
334 /* 760 MHz */
335 { 12000000, 760000000, 760, 12, 1, 12},
336 { 13000000, 760000000, 760, 13, 1, 12},
337 { 19200000, 760000000, 950, 24, 1, 8},
338 { 26000000, 760000000, 760, 26, 1, 12},
339
340 /* 750 MHz */
341 { 12000000, 750000000, 750, 12, 1, 12},
342 { 13000000, 750000000, 750, 13, 1, 12},
343 { 19200000, 750000000, 625, 16, 1, 8},
344 { 26000000, 750000000, 750, 26, 1, 12},
345
346 /* 608 MHz */
347 { 12000000, 608000000, 608, 12, 1, 12},
348 { 13000000, 608000000, 608, 13, 1, 12},
349 { 19200000, 608000000, 380, 12, 1, 8},
350 { 26000000, 608000000, 608, 26, 1, 12},
351
352 /* 456 MHz */
353 { 12000000, 456000000, 456, 12, 1, 12},
354 { 13000000, 456000000, 456, 13, 1, 12},
355 { 19200000, 456000000, 380, 16, 1, 8},
356 { 26000000, 456000000, 456, 26, 1, 12},
357
358 /* 312 MHz */
359 { 12000000, 312000000, 312, 12, 1, 12},
360 { 13000000, 312000000, 312, 13, 1, 12},
361 { 19200000, 312000000, 260, 16, 1, 8},
362 { 26000000, 312000000, 312, 26, 1, 12},
363
364 { 0, 0, 0, 0, 0, 0 },
365};
366
367static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
368 { 12000000, 100000000, 200, 24, 1, 0 },
369 { 0, 0, 0, 0, 0, 0 },
370};
371
372/* PLL parameters */
373static struct tegra_clk_pll_params pll_c_params = {
374 .input_min = 2000000,
375 .input_max = 31000000,
376 .cf_min = 1000000,
377 .cf_max = 6000000,
378 .vco_min = 20000000,
379 .vco_max = 1400000000,
380 .base_reg = PLLC_BASE,
381 .misc_reg = PLLC_MISC,
382 .lock_bit_idx = PLL_BASE_LOCK,
383 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
384 .lock_delay = 300,
385};
386
387static struct tegra_clk_pll_params pll_m_params = {
388 .input_min = 2000000,
389 .input_max = 31000000,
390 .cf_min = 1000000,
391 .cf_max = 6000000,
392 .vco_min = 20000000,
393 .vco_max = 1200000000,
394 .base_reg = PLLM_BASE,
395 .misc_reg = PLLM_MISC,
396 .lock_bit_idx = PLL_BASE_LOCK,
397 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
398 .lock_delay = 300,
399};
400
401static struct tegra_clk_pll_params pll_p_params = {
402 .input_min = 2000000,
403 .input_max = 31000000,
404 .cf_min = 1000000,
405 .cf_max = 6000000,
406 .vco_min = 20000000,
407 .vco_max = 1400000000,
408 .base_reg = PLLP_BASE,
409 .misc_reg = PLLP_MISC,
410 .lock_bit_idx = PLL_BASE_LOCK,
411 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
412 .lock_delay = 300,
413};
414
415static struct tegra_clk_pll_params pll_a_params = {
416 .input_min = 2000000,
417 .input_max = 31000000,
418 .cf_min = 1000000,
419 .cf_max = 6000000,
420 .vco_min = 20000000,
421 .vco_max = 1400000000,
422 .base_reg = PLLA_BASE,
423 .misc_reg = PLLA_MISC,
424 .lock_bit_idx = PLL_BASE_LOCK,
425 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
426 .lock_delay = 300,
427};
428
429static struct tegra_clk_pll_params pll_d_params = {
430 .input_min = 2000000,
431 .input_max = 40000000,
432 .cf_min = 1000000,
433 .cf_max = 6000000,
434 .vco_min = 40000000,
435 .vco_max = 1000000000,
436 .base_reg = PLLD_BASE,
437 .misc_reg = PLLD_MISC,
438 .lock_bit_idx = PLL_BASE_LOCK,
439 .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
440 .lock_delay = 1000,
441};
442
443static struct tegra_clk_pll_params pll_u_params = {
444 .input_min = 2000000,
445 .input_max = 40000000,
446 .cf_min = 1000000,
447 .cf_max = 6000000,
448 .vco_min = 48000000,
449 .vco_max = 960000000,
450 .base_reg = PLLU_BASE,
451 .misc_reg = PLLU_MISC,
452 .lock_bit_idx = PLL_BASE_LOCK,
453 .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
454 .lock_delay = 1000,
455};
456
457static struct tegra_clk_pll_params pll_x_params = {
458 .input_min = 2000000,
459 .input_max = 31000000,
460 .cf_min = 1000000,
461 .cf_max = 6000000,
462 .vco_min = 20000000,
463 .vco_max = 1200000000,
464 .base_reg = PLLX_BASE,
465 .misc_reg = PLLX_MISC,
466 .lock_bit_idx = PLL_BASE_LOCK,
467 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
468 .lock_delay = 300,
469};
470
471static struct tegra_clk_pll_params pll_e_params = {
472 .input_min = 12000000,
473 .input_max = 12000000,
474 .cf_min = 0,
475 .cf_max = 0,
476 .vco_min = 0,
477 .vco_max = 0,
478 .base_reg = PLLE_BASE,
479 .misc_reg = PLLE_MISC,
480 .lock_bit_idx = PLLE_MISC_LOCK,
481 .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
482 .lock_delay = 0,
483};
484
485/* Peripheral clock registers */
486static struct tegra_clk_periph_regs periph_l_regs = {
487 .enb_reg = CLK_OUT_ENB_L,
488 .enb_set_reg = CLK_OUT_ENB_SET_L,
489 .enb_clr_reg = CLK_OUT_ENB_CLR_L,
490 .rst_reg = RST_DEVICES_L,
491 .rst_set_reg = RST_DEVICES_SET_L,
492 .rst_clr_reg = RST_DEVICES_CLR_L,
493};
494
495static struct tegra_clk_periph_regs periph_h_regs = {
496 .enb_reg = CLK_OUT_ENB_H,
497 .enb_set_reg = CLK_OUT_ENB_SET_H,
498 .enb_clr_reg = CLK_OUT_ENB_CLR_H,
499 .rst_reg = RST_DEVICES_H,
500 .rst_set_reg = RST_DEVICES_SET_H,
501 .rst_clr_reg = RST_DEVICES_CLR_H,
502};
503
504static struct tegra_clk_periph_regs periph_u_regs = {
505 .enb_reg = CLK_OUT_ENB_U,
506 .enb_set_reg = CLK_OUT_ENB_SET_U,
507 .enb_clr_reg = CLK_OUT_ENB_CLR_U,
508 .rst_reg = RST_DEVICES_U,
509 .rst_set_reg = RST_DEVICES_SET_U,
510 .rst_clr_reg = RST_DEVICES_CLR_U,
511};
512
513static unsigned long tegra20_clk_measure_input_freq(void)
514{
515 u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL);
516 u32 auto_clk_control = osc_ctrl & OSC_CTRL_OSC_FREQ_MASK;
517 u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
518 unsigned long input_freq;
519
520 switch (auto_clk_control) {
521 case OSC_CTRL_OSC_FREQ_12MHZ:
522 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
523 input_freq = 12000000;
524 break;
525 case OSC_CTRL_OSC_FREQ_13MHZ:
526 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
527 input_freq = 13000000;
528 break;
529 case OSC_CTRL_OSC_FREQ_19_2MHZ:
530 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
531 input_freq = 19200000;
532 break;
533 case OSC_CTRL_OSC_FREQ_26MHZ:
534 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
535 input_freq = 26000000;
536 break;
537 default:
538 pr_err("Unexpected clock autodetect value %d",
539 auto_clk_control);
540 BUG();
541 return 0;
542 }
543
544 return input_freq;
545}
546
547static unsigned int tegra20_get_pll_ref_div(void)
548{
549 u32 pll_ref_div = readl_relaxed(clk_base + OSC_CTRL) &
550 OSC_CTRL_PLL_REF_DIV_MASK;
551
552 switch (pll_ref_div) {
553 case OSC_CTRL_PLL_REF_DIV_1:
554 return 1;
555 case OSC_CTRL_PLL_REF_DIV_2:
556 return 2;
557 case OSC_CTRL_PLL_REF_DIV_4:
558 return 4;
559 default:
560 pr_err("Invalied pll ref divider %d\n", pll_ref_div);
561 BUG();
562 }
563 return 0;
564}
565
566static void tegra20_pll_init(void)
567{
568 struct clk *clk;
569
570 /* PLLC */
571 clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0,
572 0, &pll_c_params, TEGRA_PLL_HAS_CPCON,
573 pll_c_freq_table, NULL);
574 clk_register_clkdev(clk, "pll_c", NULL);
575 clks[pll_c] = clk;
576
577 /* PLLC_OUT1 */
578 clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
579 clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
580 8, 8, 1, NULL);
581 clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div",
582 clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT,
583 0, NULL);
584 clk_register_clkdev(clk, "pll_c_out1", NULL);
585 clks[pll_c_out1] = clk;
586
587 /* PLLP */
588 clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, NULL, 0,
589 216000000, &pll_p_params, TEGRA_PLL_FIXED |
590 TEGRA_PLL_HAS_CPCON, pll_p_freq_table, NULL);
591 clk_register_clkdev(clk, "pll_p", NULL);
592 clks[pll_p] = clk;
593
594 /* PLLP_OUT1 */
595 clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p",
596 clk_base + PLLP_OUTA, 0,
597 TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP,
598 8, 8, 1, &pll_div_lock);
599 clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div",
600 clk_base + PLLP_OUTA, 1, 0,
601 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
602 &pll_div_lock);
603 clk_register_clkdev(clk, "pll_p_out1", NULL);
604 clks[pll_p_out1] = clk;
605
606 /* PLLP_OUT2 */
607 clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p",
608 clk_base + PLLP_OUTA, 0,
609 TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP,
610 24, 8, 1, &pll_div_lock);
611 clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div",
612 clk_base + PLLP_OUTA, 17, 16,
613 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
614 &pll_div_lock);
615 clk_register_clkdev(clk, "pll_p_out2", NULL);
616 clks[pll_p_out2] = clk;
617
618 /* PLLP_OUT3 */
619 clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p",
620 clk_base + PLLP_OUTB, 0,
621 TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP,
622 8, 8, 1, &pll_div_lock);
623 clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div",
624 clk_base + PLLP_OUTB, 1, 0,
625 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
626 &pll_div_lock);
627 clk_register_clkdev(clk, "pll_p_out3", NULL);
628 clks[pll_p_out3] = clk;
629
630 /* PLLP_OUT4 */
631 clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p",
632 clk_base + PLLP_OUTB, 0,
633 TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP,
634 24, 8, 1, &pll_div_lock);
635 clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div",
636 clk_base + PLLP_OUTB, 17, 16,
637 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
638 &pll_div_lock);
639 clk_register_clkdev(clk, "pll_p_out4", NULL);
640 clks[pll_p_out4] = clk;
641
642 /* PLLM */
643 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL,
644 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0,
645 &pll_m_params, TEGRA_PLL_HAS_CPCON,
646 pll_m_freq_table, NULL);
647 clk_register_clkdev(clk, "pll_m", NULL);
648 clks[pll_m] = clk;
649
650 /* PLLM_OUT1 */
651 clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m",
652 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
653 8, 8, 1, NULL);
654 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
655 clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED |
656 CLK_SET_RATE_PARENT, 0, NULL);
657 clk_register_clkdev(clk, "pll_m_out1", NULL);
658 clks[pll_m_out1] = clk;
659
660 /* PLLX */
661 clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, NULL, 0,
662 0, &pll_x_params, TEGRA_PLL_HAS_CPCON,
663 pll_x_freq_table, NULL);
664 clk_register_clkdev(clk, "pll_x", NULL);
665 clks[pll_x] = clk;
666
667 /* PLLU */
668 clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, NULL, 0,
669 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON,
670 pll_u_freq_table, NULL);
671 clk_register_clkdev(clk, "pll_u", NULL);
672 clks[pll_u] = clk;
673
674 /* PLLD */
675 clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, NULL, 0,
676 0, &pll_d_params, TEGRA_PLL_HAS_CPCON,
677 pll_d_freq_table, NULL);
678 clk_register_clkdev(clk, "pll_d", NULL);
679 clks[pll_d] = clk;
680
681 /* PLLD_OUT0 */
682 clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d",
683 CLK_SET_RATE_PARENT, 1, 2);
684 clk_register_clkdev(clk, "pll_d_out0", NULL);
685 clks[pll_d_out0] = clk;
686
687 /* PLLA */
688 clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, NULL, 0,
689 0, &pll_a_params, TEGRA_PLL_HAS_CPCON,
690 pll_a_freq_table, NULL);
691 clk_register_clkdev(clk, "pll_a", NULL);
692 clks[pll_a] = clk;
693
694 /* PLLA_OUT0 */
695 clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a",
696 clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
697 8, 8, 1, NULL);
698 clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div",
699 clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED |
700 CLK_SET_RATE_PARENT, 0, NULL);
701 clk_register_clkdev(clk, "pll_a_out0", NULL);
702 clks[pll_a_out0] = clk;
703
704 /* PLLE */
705 clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, NULL,
706 0, 100000000, &pll_e_params,
707 0, pll_e_freq_table, NULL);
708 clk_register_clkdev(clk, "pll_e", NULL);
709 clks[pll_e] = clk;
710}
711
712static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
713 "pll_p_cclk", "pll_p_out4_cclk",
714 "pll_p_out3_cclk", "clk_d", "pll_x" };
715static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
716 "pll_p_out3", "pll_p_out2", "clk_d",
717 "clk_32k", "pll_m_out1" };
718
719static void tegra20_super_clk_init(void)
720{
721 struct clk *clk;
722
723 /*
724 * DIV_U71 dividers for CCLK, these dividers are used only
725 * if parent clock is fixed rate.
726 */
727
728 /*
729 * Clock input to cclk divided from pll_p using
730 * U71 divider of cclk.
731 */
732 clk = tegra_clk_register_divider("pll_p_cclk", "pll_p",
733 clk_base + SUPER_CCLK_DIVIDER, 0,
734 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
735 clk_register_clkdev(clk, "pll_p_cclk", NULL);
736
737 /*
738 * Clock input to cclk divided from pll_p_out3 using
739 * U71 divider of cclk.
740 */
741 clk = tegra_clk_register_divider("pll_p_out3_cclk", "pll_p_out3",
742 clk_base + SUPER_CCLK_DIVIDER, 0,
743 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
744 clk_register_clkdev(clk, "pll_p_out3_cclk", NULL);
745
746 /*
747 * Clock input to cclk divided from pll_p_out4 using
748 * U71 divider of cclk.
749 */
750 clk = tegra_clk_register_divider("pll_p_out4_cclk", "pll_p_out4",
751 clk_base + SUPER_CCLK_DIVIDER, 0,
752 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
753 clk_register_clkdev(clk, "pll_p_out4_cclk", NULL);
754
755 /* CCLK */
756 clk = tegra_clk_register_super_mux("cclk", cclk_parents,
757 ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT,
758 clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
759 clk_register_clkdev(clk, "cclk", NULL);
760 clks[cclk] = clk;
761
762 /* SCLK */
763 clk = tegra_clk_register_super_mux("sclk", sclk_parents,
764 ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT,
765 clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
766 clk_register_clkdev(clk, "sclk", NULL);
767 clks[sclk] = clk;
768
769 /* HCLK */
770 clk = clk_register_divider(NULL, "hclk_div", "sclk", 0,
771 clk_base + CLK_SYSTEM_RATE, 4, 2, 0, NULL);
772 clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT,
773 clk_base + CLK_SYSTEM_RATE, 7,
774 CLK_GATE_SET_TO_DISABLE, NULL);
775 clk_register_clkdev(clk, "hclk", NULL);
776 clks[hclk] = clk;
777
778 /* PCLK */
779 clk = clk_register_divider(NULL, "pclk_div", "hclk", 0,
780 clk_base + CLK_SYSTEM_RATE, 0, 2, 0, NULL);
781 clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT,
782 clk_base + CLK_SYSTEM_RATE, 3,
783 CLK_GATE_SET_TO_DISABLE, NULL);
784 clk_register_clkdev(clk, "pclk", NULL);
785 clks[pclk] = clk;
786
787 /* twd */
788 clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4);
789 clk_register_clkdev(clk, "twd", NULL);
790 clks[twd] = clk;
791}
792
793static const char *audio_parents[] = {"spdif_in", "i2s1", "i2s2", "unused",
794 "pll_a_out0", "unused", "unused",
795 "unused"};
796
797static void __init tegra20_audio_clk_init(void)
798{
799 struct clk *clk;
800
801 /* audio */
802 clk = clk_register_mux(NULL, "audio_mux", audio_parents,
803 ARRAY_SIZE(audio_parents), 0,
804 clk_base + AUDIO_SYNC_CLK, 0, 3, 0, NULL);
805 clk = clk_register_gate(NULL, "audio", "audio_mux", 0,
806 clk_base + AUDIO_SYNC_CLK, 4,
807 CLK_GATE_SET_TO_DISABLE, NULL);
808 clk_register_clkdev(clk, "audio", NULL);
809 clks[audio] = clk;
810
811 /* audio_2x */
812 clk = clk_register_fixed_factor(NULL, "audio_doubler", "audio",
813 CLK_SET_RATE_PARENT, 2, 1);
814 clk = tegra_clk_register_periph_gate("audio_2x", "audio_doubler",
815 TEGRA_PERIPH_NO_RESET, clk_base,
816 CLK_SET_RATE_PARENT, 89, &periph_u_regs,
817 periph_clk_enb_refcnt);
818 clk_register_clkdev(clk, "audio_2x", NULL);
819 clks[audio_2x] = clk;
820
821}
822
823static const char *i2s1_parents[] = {"pll_a_out0", "audio_2x", "pll_p",
824 "clk_m"};
825static const char *i2s2_parents[] = {"pll_a_out0", "audio_2x", "pll_p",
826 "clk_m"};
827static const char *spdif_out_parents[] = {"pll_a_out0", "audio_2x", "pll_p",
828 "clk_m"};
829static const char *spdif_in_parents[] = {"pll_p", "pll_c", "pll_m"};
830static const char *pwm_parents[] = {"pll_p", "pll_c", "audio", "clk_m",
831 "clk_32k"};
832static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"};
833static const char *mux_pllmcpa[] = {"pll_m", "pll_c", "pll_c", "pll_a"};
834static const char *mux_pllpdc_clkm[] = {"pll_p", "pll_d_out0", "pll_c",
835 "clk_m"};
836static const char *mux_pllmcp_clkm[] = {"pll_m", "pll_c", "pll_p", "clk_m"};
837
838static struct tegra_periph_init_data tegra_periph_clk_list[] = {
839 TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra20-i2s.0", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1),
840 TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra20-i2s.1", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2),
841 TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra20-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out),
842 TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra20-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in),
843 TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1),
844 TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2),
845 TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3),
846 TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4),
847 TEGRA_INIT_DATA_MUX("spi", NULL, "spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, &periph_h_regs, TEGRA_PERIPH_ON_APB, spi),
848 TEGRA_INIT_DATA_MUX("xio", NULL, "xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, &periph_h_regs, 0, xio),
849 TEGRA_INIT_DATA_MUX("twc", NULL, "twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, &periph_l_regs, TEGRA_PERIPH_ON_APB, twc),
850 TEGRA_INIT_DATA_MUX("ide", NULL, "ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, &periph_l_regs, 0, ide),
851 TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, 0, ndflash),
852 TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir),
853 TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, 0, csite),
854 TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, 0, la),
855 TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr),
856 TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi),
857 TEGRA_INIT_DATA_MUX("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde),
858 TEGRA_INIT_DATA_MUX("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi),
859 TEGRA_INIT_DATA_MUX("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp),
860 TEGRA_INIT_DATA_MUX("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe),
861 TEGRA_INIT_DATA_MUX("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x),
862 TEGRA_INIT_DATA_MUX("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d),
863 TEGRA_INIT_DATA_MUX("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d),
864 TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor),
865 TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1),
866 TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2),
867 TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3),
868 TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4),
869 TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve),
870 TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo),
871 TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac),
872 TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor),
873 TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1),
874 TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2),
875 TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3),
876 TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, dvc),
877 TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi),
878 TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm),
879};
880
881static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
882 TEGRA_INIT_DATA_NODIV("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, &periph_l_regs, TEGRA_PERIPH_ON_APB, uarta),
883 TEGRA_INIT_DATA_NODIV("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, uartb),
884 TEGRA_INIT_DATA_NODIV("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, &periph_h_regs, TEGRA_PERIPH_ON_APB, uartc),
885 TEGRA_INIT_DATA_NODIV("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, &periph_u_regs, TEGRA_PERIPH_ON_APB, uartd),
886 TEGRA_INIT_DATA_NODIV("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, &periph_u_regs, TEGRA_PERIPH_ON_APB, uarte),
887 TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, &periph_l_regs, 0, disp1),
888 TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, &periph_l_regs, 0, disp2),
889};
890
891static void __init tegra20_periph_clk_init(void)
892{
893 struct tegra_periph_init_data *data;
894 struct clk *clk;
895 int i;
896
897 /* apbdma */
898 clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base,
899 0, 34, &periph_h_regs,
900 periph_clk_enb_refcnt);
901 clk_register_clkdev(clk, NULL, "tegra-apbdma");
902 clks[apbdma] = clk;
903
904 /* rtc */
905 clk = tegra_clk_register_periph_gate("rtc", "clk_32k",
906 TEGRA_PERIPH_NO_RESET,
907 clk_base, 0, 4, &periph_l_regs,
908 periph_clk_enb_refcnt);
909 clk_register_clkdev(clk, NULL, "rtc-tegra");
910 clks[rtc] = clk;
911
912 /* timer */
913 clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base,
914 0, 5, &periph_l_regs,
915 periph_clk_enb_refcnt);
916 clk_register_clkdev(clk, NULL, "timer");
917 clks[timer] = clk;
918
919 /* kbc */
920 clk = tegra_clk_register_periph_gate("kbc", "clk_32k",
921 TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB,
922 clk_base, 0, 36, &periph_h_regs,
923 periph_clk_enb_refcnt);
924 clk_register_clkdev(clk, NULL, "tegra-kbc");
925 clks[kbc] = clk;
926
927 /* csus */
928 clk = tegra_clk_register_periph_gate("csus", "clk_m",
929 TEGRA_PERIPH_NO_RESET,
930 clk_base, 0, 92, &periph_u_regs,
931 periph_clk_enb_refcnt);
932 clk_register_clkdev(clk, "csus", "tengra_camera");
933 clks[csus] = clk;
934
935 /* vcp */
936 clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0,
937 clk_base, 0, 29, &periph_l_regs,
938 periph_clk_enb_refcnt);
939 clk_register_clkdev(clk, "vcp", "tegra-avp");
940 clks[vcp] = clk;
941
942 /* bsea */
943 clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0,
944 clk_base, 0, 62, &periph_h_regs,
945 periph_clk_enb_refcnt);
946 clk_register_clkdev(clk, "bsea", "tegra-avp");
947 clks[bsea] = clk;
948
949 /* bsev */
950 clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0,
951 clk_base, 0, 63, &periph_h_regs,
952 periph_clk_enb_refcnt);
953 clk_register_clkdev(clk, "bsev", "tegra-aes");
954 clks[bsev] = clk;
955
956 /* emc */
957 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
958 ARRAY_SIZE(mux_pllmcp_clkm), 0,
959 clk_base + CLK_SOURCE_EMC,
960 30, 2, 0, NULL);
961 clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
962 57, &periph_h_regs, periph_clk_enb_refcnt);
963 clk_register_clkdev(clk, "emc", NULL);
964 clks[emc] = clk;
965
966 /* usbd */
967 clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0,
968 22, &periph_l_regs, periph_clk_enb_refcnt);
969 clk_register_clkdev(clk, NULL, "fsl-tegra-udc");
970 clks[usbd] = clk;
971
972 /* usb2 */
973 clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0,
974 58, &periph_h_regs, periph_clk_enb_refcnt);
975 clk_register_clkdev(clk, NULL, "tegra-ehci.1");
976 clks[usb2] = clk;
977
978 /* usb3 */
979 clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0,
980 59, &periph_h_regs, periph_clk_enb_refcnt);
981 clk_register_clkdev(clk, NULL, "tegra-ehci.2");
982 clks[usb3] = clk;
983
984 /* dsi */
985 clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0,
986 48, &periph_h_regs, periph_clk_enb_refcnt);
987 clk_register_clkdev(clk, NULL, "dsi");
988 clks[dsi] = clk;
989
990 /* csi */
991 clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base,
992 0, 52, &periph_h_regs,
993 periph_clk_enb_refcnt);
994 clk_register_clkdev(clk, "csi", "tegra_camera");
995 clks[csi] = clk;
996
997 /* isp */
998 clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23,
999 &periph_l_regs, periph_clk_enb_refcnt);
1000 clk_register_clkdev(clk, "isp", "tegra_camera");
1001 clks[isp] = clk;
1002
1003 /* pex */
1004 clk = tegra_clk_register_periph_gate("pex", "clk_m", 0, clk_base, 0, 70,
1005 &periph_u_regs, periph_clk_enb_refcnt);
1006 clk_register_clkdev(clk, "pex", NULL);
1007 clks[pex] = clk;
1008
1009 /* afi */
1010 clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72,
1011 &periph_u_regs, periph_clk_enb_refcnt);
1012 clk_register_clkdev(clk, "afi", NULL);
1013 clks[afi] = clk;
1014
1015 /* pcie_xclk */
1016 clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base,
1017 0, 74, &periph_u_regs,
1018 periph_clk_enb_refcnt);
1019 clk_register_clkdev(clk, "pcie_xclk", NULL);
1020 clks[pcie_xclk] = clk;
1021
1022 /* cdev1 */
1023 clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT,
1024 26000000);
1025 clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0,
1026 clk_base, 0, 94, &periph_u_regs,
1027 periph_clk_enb_refcnt);
1028 clk_register_clkdev(clk, "cdev1", NULL);
1029 clks[cdev1] = clk;
1030
1031 /* cdev2 */
1032 clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT,
1033 26000000);
1034 clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0,
1035 clk_base, 0, 93, &periph_u_regs,
1036 periph_clk_enb_refcnt);
1037 clk_register_clkdev(clk, "cdev2", NULL);
1038 clks[cdev2] = clk;
1039
1040 for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
1041 data = &tegra_periph_clk_list[i];
1042 clk = tegra_clk_register_periph(data->name, data->parent_names,
1043 data->num_parents, &data->periph,
1044 clk_base, data->offset);
1045 clk_register_clkdev(clk, data->con_id, data->dev_id);
1046 clks[data->clk_id] = clk;
1047 }
1048
1049 for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) {
1050 data = &tegra_periph_nodiv_clk_list[i];
1051 clk = tegra_clk_register_periph_nodiv(data->name,
1052 data->parent_names,
1053 data->num_parents, &data->periph,
1054 clk_base, data->offset);
1055 clk_register_clkdev(clk, data->con_id, data->dev_id);
1056 clks[data->clk_id] = clk;
1057 }
1058}
1059
1060
1061static void __init tegra20_fixed_clk_init(void)
1062{
1063 struct clk *clk;
1064
1065 /* clk_32k */
1066 clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT,
1067 32768);
1068 clk_register_clkdev(clk, "clk_32k", NULL);
1069 clks[clk_32k] = clk;
1070}
1071
1072static void __init tegra20_pmc_clk_init(void)
1073{
1074 struct clk *clk;
1075
1076 /* blink */
1077 writel_relaxed(0, pmc_base + PMC_BLINK_TIMER);
1078 clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0,
1079 pmc_base + PMC_DPD_PADS_ORIDE,
1080 PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL);
1081 clk = clk_register_gate(NULL, "blink", "blink_override", 0,
1082 pmc_base + PMC_CTRL,
1083 PMC_CTRL_BLINK_ENB, 0, NULL);
1084 clk_register_clkdev(clk, "blink", NULL);
1085 clks[blink] = clk;
1086}
1087
1088static void __init tegra20_osc_clk_init(void)
1089{
1090 struct clk *clk;
1091 unsigned long input_freq;
1092 unsigned int pll_ref_div;
1093
1094 input_freq = tegra20_clk_measure_input_freq();
1095
1096 /* clk_m */
1097 clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT |
1098 CLK_IGNORE_UNUSED, input_freq);
1099 clk_register_clkdev(clk, "clk_m", NULL);
1100 clks[clk_m] = clk;
1101
1102 /* pll_ref */
1103 pll_ref_div = tegra20_get_pll_ref_div();
1104 clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m",
1105 CLK_SET_RATE_PARENT, 1, pll_ref_div);
1106 clk_register_clkdev(clk, "pll_ref", NULL);
1107 clks[pll_ref] = clk;
1108}
1109
1110/* Tegra20 CPU clock and reset control functions */
1111static void tegra20_wait_cpu_in_reset(u32 cpu)
1112{
1113 unsigned int reg;
1114
1115 do {
1116 reg = readl(clk_base +
1117 TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
1118 cpu_relax();
1119 } while (!(reg & (1 << cpu))); /* check CPU been reset or not */
1120
1121 return;
1122}
1123
1124static void tegra20_put_cpu_in_reset(u32 cpu)
1125{
1126 writel(CPU_RESET(cpu),
1127 clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
1128 dmb();
1129}
1130
1131static void tegra20_cpu_out_of_reset(u32 cpu)
1132{
1133 writel(CPU_RESET(cpu),
1134 clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
1135 wmb();
1136}
1137
1138static void tegra20_enable_cpu_clock(u32 cpu)
1139{
1140 unsigned int reg;
1141
1142 reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1143 writel(reg & ~CPU_CLOCK(cpu),
1144 clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1145 barrier();
1146 reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1147}
1148
1149static void tegra20_disable_cpu_clock(u32 cpu)
1150{
1151 unsigned int reg;
1152
1153 reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1154 writel(reg | CPU_CLOCK(cpu),
1155 clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1156}
1157
1158#ifdef CONFIG_PM_SLEEP
1159static bool tegra20_cpu_rail_off_ready(void)
1160{
1161 unsigned int cpu_rst_status;
1162
1163 cpu_rst_status = readl(clk_base +
1164 TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
1165
1166 return !!(cpu_rst_status & 0x2);
1167}
1168
1169static void tegra20_cpu_clock_suspend(void)
1170{
1171 /* switch coresite to clk_m, save off original source */
1172 tegra20_cpu_clk_sctx.clk_csite_src =
1173 readl(clk_base + CLK_SOURCE_CSITE);
1174 writel(3<<30, clk_base + CLK_SOURCE_CSITE);
1175
1176 tegra20_cpu_clk_sctx.cpu_burst =
1177 readl(clk_base + CCLK_BURST_POLICY);
1178 tegra20_cpu_clk_sctx.pllx_base =
1179 readl(clk_base + PLLX_BASE);
1180 tegra20_cpu_clk_sctx.pllx_misc =
1181 readl(clk_base + PLLX_MISC);
1182 tegra20_cpu_clk_sctx.cclk_divider =
1183 readl(clk_base + SUPER_CCLK_DIVIDER);
1184}
1185
1186static void tegra20_cpu_clock_resume(void)
1187{
1188 unsigned int reg, policy;
1189
1190 /* Is CPU complex already running on PLLX? */
1191 reg = readl(clk_base + CCLK_BURST_POLICY);
1192 policy = (reg >> CCLK_BURST_POLICY_SHIFT) & 0xF;
1193
1194 if (policy == CCLK_IDLE_POLICY)
1195 reg = (reg >> CCLK_IDLE_POLICY_SHIFT) & 0xF;
1196 else if (policy == CCLK_RUN_POLICY)
1197 reg = (reg >> CCLK_RUN_POLICY_SHIFT) & 0xF;
1198 else
1199 BUG();
1200
1201 if (reg != CCLK_BURST_POLICY_PLLX) {
1202 /* restore PLLX settings if CPU is on different PLL */
1203 writel(tegra20_cpu_clk_sctx.pllx_misc,
1204 clk_base + PLLX_MISC);
1205 writel(tegra20_cpu_clk_sctx.pllx_base,
1206 clk_base + PLLX_BASE);
1207
1208 /* wait for PLL stabilization if PLLX was enabled */
1209 if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30))
1210 udelay(300);
1211 }
1212
1213 /*
1214 * Restore original burst policy setting for calls resulting from CPU
1215 * LP2 in idle or system suspend.
1216 */
1217 writel(tegra20_cpu_clk_sctx.cclk_divider,
1218 clk_base + SUPER_CCLK_DIVIDER);
1219 writel(tegra20_cpu_clk_sctx.cpu_burst,
1220 clk_base + CCLK_BURST_POLICY);
1221
1222 writel(tegra20_cpu_clk_sctx.clk_csite_src,
1223 clk_base + CLK_SOURCE_CSITE);
1224}
1225#endif
1226
1227static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
1228 .wait_for_reset = tegra20_wait_cpu_in_reset,
1229 .put_in_reset = tegra20_put_cpu_in_reset,
1230 .out_of_reset = tegra20_cpu_out_of_reset,
1231 .enable_clock = tegra20_enable_cpu_clock,
1232 .disable_clock = tegra20_disable_cpu_clock,
1233#ifdef CONFIG_PM_SLEEP
1234 .rail_off_ready = tegra20_cpu_rail_off_ready,
1235 .suspend = tegra20_cpu_clock_suspend,
1236 .resume = tegra20_cpu_clock_resume,
1237#endif
1238};
1239
1240static __initdata struct tegra_clk_init_table init_table[] = {
1241 {pll_p, clk_max, 216000000, 1},
1242 {pll_p_out1, clk_max, 28800000, 1},
1243 {pll_p_out2, clk_max, 48000000, 1},
1244 {pll_p_out3, clk_max, 72000000, 1},
1245 {pll_p_out4, clk_max, 24000000, 1},
1246 {pll_c, clk_max, 600000000, 1},
1247 {pll_c_out1, clk_max, 120000000, 1},
1248 {sclk, pll_c_out1, 0, 1},
1249 {hclk, clk_max, 0, 1},
1250 {pclk, clk_max, 60000000, 1},
1251 {csite, clk_max, 0, 1},
1252 {emc, clk_max, 0, 1},
1253 {cclk, clk_max, 0, 1},
1254 {uarta, pll_p, 0, 1},
1255 {uartd, pll_p, 0, 1},
1256 {usbd, clk_max, 12000000, 0},
1257 {usb2, clk_max, 12000000, 0},
1258 {usb3, clk_max, 12000000, 0},
1259 {pll_a, clk_max, 56448000, 1},
1260 {pll_a_out0, clk_max, 11289600, 1},
1261 {cdev1, clk_max, 0, 1},
1262 {blink, clk_max, 32768, 1},
1263 {i2s1, pll_a_out0, 11289600, 0},
1264 {i2s2, pll_a_out0, 11289600, 0},
1265 {sdmmc1, pll_p, 48000000, 0},
1266 {sdmmc3, pll_p, 48000000, 0},
1267 {sdmmc4, pll_p, 48000000, 0},
1268 {spi, pll_p, 20000000, 0},
1269 {sbc1, pll_p, 100000000, 0},
1270 {sbc2, pll_p, 100000000, 0},
1271 {sbc3, pll_p, 100000000, 0},
1272 {sbc4, pll_p, 100000000, 0},
1273 {host1x, pll_c, 150000000, 0},
1274 {disp1, pll_p, 600000000, 0},
1275 {disp2, pll_p, 600000000, 0},
1276 {clk_max, clk_max, 0, 0}, /* This MUST be the last entry */
1277};
1278
1279/*
1280 * Some clocks may be used by different drivers depending on the board
1281 * configuration. List those here to register them twice in the clock lookup
1282 * table under two names.
1283 */
1284static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
1285 TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL),
1286 TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL),
1287 TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL),
1288 TEGRA_CLK_DUPLICATE(cclk, NULL, "cpu"),
1289 TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL),
1290 TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */
1291};
1292
1293static const struct of_device_id pmc_match[] __initconst = {
1294 { .compatible = "nvidia,tegra20-pmc" },
1295 {},
1296};
1297
1298void __init tegra20_clock_init(struct device_node *np)
1299{
1300 int i;
1301 struct device_node *node;
1302
1303 clk_base = of_iomap(np, 0);
1304 if (!clk_base) {
1305 pr_err("Can't map CAR registers\n");
1306 BUG();
1307 }
1308
1309 node = of_find_matching_node(NULL, pmc_match);
1310 if (!node) {
1311 pr_err("Failed to find pmc node\n");
1312 BUG();
1313 }
1314
1315 pmc_base = of_iomap(node, 0);
1316 if (!pmc_base) {
1317 pr_err("Can't map pmc registers\n");
1318 BUG();
1319 }
1320
1321 tegra20_osc_clk_init();
1322 tegra20_pmc_clk_init();
1323 tegra20_fixed_clk_init();
1324 tegra20_pll_init();
1325 tegra20_super_clk_init();
1326 tegra20_periph_clk_init();
1327 tegra20_audio_clk_init();
1328
1329
1330 for (i = 0; i < ARRAY_SIZE(clks); i++) {
1331 if (IS_ERR(clks[i])) {
1332 pr_err("Tegra20 clk %d: register failed with %ld\n",
1333 i, PTR_ERR(clks[i]));
1334 BUG();
1335 }
1336 if (!clks[i])
1337 clks[i] = ERR_PTR(-EINVAL);
1338 }
1339
1340 tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max);
1341
1342 clk_data.clks = clks;
1343 clk_data.clk_num = ARRAY_SIZE(clks);
1344 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1345
1346 tegra_init_from_table(init_table, clks, clk_max);
1347
1348 tegra_cpu_car_ops = &tegra20_cpu_car_ops;
1349}
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
new file mode 100644
index 000000000000..a1638129eba4
--- /dev/null
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -0,0 +1,1987 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/io.h>
18#include <linux/delay.h>
19#include <linux/clk.h>
20#include <linux/clk-provider.h>
21#include <linux/clkdev.h>
22#include <linux/of.h>
23#include <linux/of_address.h>
24#include <linux/clk/tegra.h>
25
26#include <mach/powergate.h>
27
28#include "clk.h"
29
30#define RST_DEVICES_L 0x004
31#define RST_DEVICES_H 0x008
32#define RST_DEVICES_U 0x00c
33#define RST_DEVICES_V 0x358
34#define RST_DEVICES_W 0x35c
35#define RST_DEVICES_SET_L 0x300
36#define RST_DEVICES_CLR_L 0x304
37#define RST_DEVICES_SET_H 0x308
38#define RST_DEVICES_CLR_H 0x30c
39#define RST_DEVICES_SET_U 0x310
40#define RST_DEVICES_CLR_U 0x314
41#define RST_DEVICES_SET_V 0x430
42#define RST_DEVICES_CLR_V 0x434
43#define RST_DEVICES_SET_W 0x438
44#define RST_DEVICES_CLR_W 0x43c
45#define RST_DEVICES_NUM 5
46
47#define CLK_OUT_ENB_L 0x010
48#define CLK_OUT_ENB_H 0x014
49#define CLK_OUT_ENB_U 0x018
50#define CLK_OUT_ENB_V 0x360
51#define CLK_OUT_ENB_W 0x364
52#define CLK_OUT_ENB_SET_L 0x320
53#define CLK_OUT_ENB_CLR_L 0x324
54#define CLK_OUT_ENB_SET_H 0x328
55#define CLK_OUT_ENB_CLR_H 0x32c
56#define CLK_OUT_ENB_SET_U 0x330
57#define CLK_OUT_ENB_CLR_U 0x334
58#define CLK_OUT_ENB_SET_V 0x440
59#define CLK_OUT_ENB_CLR_V 0x444
60#define CLK_OUT_ENB_SET_W 0x448
61#define CLK_OUT_ENB_CLR_W 0x44c
62#define CLK_OUT_ENB_NUM 5
63
64#define OSC_CTRL 0x50
65#define OSC_CTRL_OSC_FREQ_MASK (0xF<<28)
66#define OSC_CTRL_OSC_FREQ_13MHZ (0X0<<28)
67#define OSC_CTRL_OSC_FREQ_19_2MHZ (0X4<<28)
68#define OSC_CTRL_OSC_FREQ_12MHZ (0X8<<28)
69#define OSC_CTRL_OSC_FREQ_26MHZ (0XC<<28)
70#define OSC_CTRL_OSC_FREQ_16_8MHZ (0X1<<28)
71#define OSC_CTRL_OSC_FREQ_38_4MHZ (0X5<<28)
72#define OSC_CTRL_OSC_FREQ_48MHZ (0X9<<28)
73#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
74
75#define OSC_CTRL_PLL_REF_DIV_MASK (3<<26)
76#define OSC_CTRL_PLL_REF_DIV_1 (0<<26)
77#define OSC_CTRL_PLL_REF_DIV_2 (1<<26)
78#define OSC_CTRL_PLL_REF_DIV_4 (2<<26)
79
80#define OSC_FREQ_DET 0x58
81#define OSC_FREQ_DET_TRIG BIT(31)
82
83#define OSC_FREQ_DET_STATUS 0x5c
84#define OSC_FREQ_DET_BUSY BIT(31)
85#define OSC_FREQ_DET_CNT_MASK 0xffff
86
87#define CCLKG_BURST_POLICY 0x368
88#define SUPER_CCLKG_DIVIDER 0x36c
89#define CCLKLP_BURST_POLICY 0x370
90#define SUPER_CCLKLP_DIVIDER 0x374
91#define SCLK_BURST_POLICY 0x028
92#define SUPER_SCLK_DIVIDER 0x02c
93
94#define SYSTEM_CLK_RATE 0x030
95
96#define PLLC_BASE 0x80
97#define PLLC_MISC 0x8c
98#define PLLM_BASE 0x90
99#define PLLM_MISC 0x9c
100#define PLLP_BASE 0xa0
101#define PLLP_MISC 0xac
102#define PLLX_BASE 0xe0
103#define PLLX_MISC 0xe4
104#define PLLD_BASE 0xd0
105#define PLLD_MISC 0xdc
106#define PLLD2_BASE 0x4b8
107#define PLLD2_MISC 0x4bc
108#define PLLE_BASE 0xe8
109#define PLLE_MISC 0xec
110#define PLLA_BASE 0xb0
111#define PLLA_MISC 0xbc
112#define PLLU_BASE 0xc0
113#define PLLU_MISC 0xcc
114
115#define PLL_MISC_LOCK_ENABLE 18
116#define PLLDU_MISC_LOCK_ENABLE 22
117#define PLLE_MISC_LOCK_ENABLE 9
118
119#define PLL_BASE_LOCK 27
120#define PLLE_MISC_LOCK 11
121
122#define PLLE_AUX 0x48c
123#define PLLC_OUT 0x84
124#define PLLM_OUT 0x94
125#define PLLP_OUTA 0xa4
126#define PLLP_OUTB 0xa8
127#define PLLA_OUT 0xb4
128
129#define AUDIO_SYNC_CLK_I2S0 0x4a0
130#define AUDIO_SYNC_CLK_I2S1 0x4a4
131#define AUDIO_SYNC_CLK_I2S2 0x4a8
132#define AUDIO_SYNC_CLK_I2S3 0x4ac
133#define AUDIO_SYNC_CLK_I2S4 0x4b0
134#define AUDIO_SYNC_CLK_SPDIF 0x4b4
135
136#define PMC_CLK_OUT_CNTRL 0x1a8
137
138#define CLK_SOURCE_I2S0 0x1d8
139#define CLK_SOURCE_I2S1 0x100
140#define CLK_SOURCE_I2S2 0x104
141#define CLK_SOURCE_I2S3 0x3bc
142#define CLK_SOURCE_I2S4 0x3c0
143#define CLK_SOURCE_SPDIF_OUT 0x108
144#define CLK_SOURCE_SPDIF_IN 0x10c
145#define CLK_SOURCE_PWM 0x110
146#define CLK_SOURCE_D_AUDIO 0x3d0
147#define CLK_SOURCE_DAM0 0x3d8
148#define CLK_SOURCE_DAM1 0x3dc
149#define CLK_SOURCE_DAM2 0x3e0
150#define CLK_SOURCE_HDA 0x428
151#define CLK_SOURCE_HDA2CODEC_2X 0x3e4
152#define CLK_SOURCE_SBC1 0x134
153#define CLK_SOURCE_SBC2 0x118
154#define CLK_SOURCE_SBC3 0x11c
155#define CLK_SOURCE_SBC4 0x1b4
156#define CLK_SOURCE_SBC5 0x3c8
157#define CLK_SOURCE_SBC6 0x3cc
158#define CLK_SOURCE_SATA_OOB 0x420
159#define CLK_SOURCE_SATA 0x424
160#define CLK_SOURCE_NDFLASH 0x160
161#define CLK_SOURCE_NDSPEED 0x3f8
162#define CLK_SOURCE_VFIR 0x168
163#define CLK_SOURCE_SDMMC1 0x150
164#define CLK_SOURCE_SDMMC2 0x154
165#define CLK_SOURCE_SDMMC3 0x1bc
166#define CLK_SOURCE_SDMMC4 0x164
167#define CLK_SOURCE_VDE 0x1c8
168#define CLK_SOURCE_CSITE 0x1d4
169#define CLK_SOURCE_LA 0x1f8
170#define CLK_SOURCE_OWR 0x1cc
171#define CLK_SOURCE_NOR 0x1d0
172#define CLK_SOURCE_MIPI 0x174
173#define CLK_SOURCE_I2C1 0x124
174#define CLK_SOURCE_I2C2 0x198
175#define CLK_SOURCE_I2C3 0x1b8
176#define CLK_SOURCE_I2C4 0x3c4
177#define CLK_SOURCE_I2C5 0x128
178#define CLK_SOURCE_UARTA 0x178
179#define CLK_SOURCE_UARTB 0x17c
180#define CLK_SOURCE_UARTC 0x1a0
181#define CLK_SOURCE_UARTD 0x1c0
182#define CLK_SOURCE_UARTE 0x1c4
183#define CLK_SOURCE_VI 0x148
184#define CLK_SOURCE_VI_SENSOR 0x1a8
185#define CLK_SOURCE_3D 0x158
186#define CLK_SOURCE_3D2 0x3b0
187#define CLK_SOURCE_2D 0x15c
188#define CLK_SOURCE_EPP 0x16c
189#define CLK_SOURCE_MPE 0x170
190#define CLK_SOURCE_HOST1X 0x180
191#define CLK_SOURCE_CVE 0x140
192#define CLK_SOURCE_TVO 0x188
193#define CLK_SOURCE_DTV 0x1dc
194#define CLK_SOURCE_HDMI 0x18c
195#define CLK_SOURCE_TVDAC 0x194
196#define CLK_SOURCE_DISP1 0x138
197#define CLK_SOURCE_DISP2 0x13c
198#define CLK_SOURCE_DSIB 0xd0
199#define CLK_SOURCE_TSENSOR 0x3b8
200#define CLK_SOURCE_ACTMON 0x3e8
201#define CLK_SOURCE_EXTERN1 0x3ec
202#define CLK_SOURCE_EXTERN2 0x3f0
203#define CLK_SOURCE_EXTERN3 0x3f4
204#define CLK_SOURCE_I2CSLOW 0x3fc
205#define CLK_SOURCE_SE 0x42c
206#define CLK_SOURCE_MSELECT 0x3b4
207#define CLK_SOURCE_EMC 0x19c
208
209#define AUDIO_SYNC_DOUBLER 0x49c
210
211#define PMC_CTRL 0
212#define PMC_CTRL_BLINK_ENB 7
213
214#define PMC_DPD_PADS_ORIDE 0x1c
215#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20
216#define PMC_BLINK_TIMER 0x40
217
218#define UTMIP_PLL_CFG2 0x488
219#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6)
220#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
221#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0)
222#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2)
223#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4)
224
225#define UTMIP_PLL_CFG1 0x484
226#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6)
227#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
228#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14)
229#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12)
230#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16)
231
232/* Tegra CPU clock and reset control regs */
233#define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c
234#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340
235#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344
236#define TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR 0x34c
237#define TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
238
239#define CPU_CLOCK(cpu) (0x1 << (8 + cpu))
240#define CPU_RESET(cpu) (0x1111ul << (cpu))
241
242#define CLK_RESET_CCLK_BURST 0x20
243#define CLK_RESET_CCLK_DIVIDER 0x24
244#define CLK_RESET_PLLX_BASE 0xe0
245#define CLK_RESET_PLLX_MISC 0xe4
246
247#define CLK_RESET_SOURCE_CSITE 0x1d4
248
249#define CLK_RESET_CCLK_BURST_POLICY_SHIFT 28
250#define CLK_RESET_CCLK_RUN_POLICY_SHIFT 4
251#define CLK_RESET_CCLK_IDLE_POLICY_SHIFT 0
252#define CLK_RESET_CCLK_IDLE_POLICY 1
253#define CLK_RESET_CCLK_RUN_POLICY 2
254#define CLK_RESET_CCLK_BURST_POLICY_PLLX 8
255
256#ifdef CONFIG_PM_SLEEP
257static struct cpu_clk_suspend_context {
258 u32 pllx_misc;
259 u32 pllx_base;
260
261 u32 cpu_burst;
262 u32 clk_csite_src;
263 u32 cclk_divider;
264} tegra30_cpu_clk_sctx;
265#endif
266
267static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
268
269static void __iomem *clk_base;
270static void __iomem *pmc_base;
271static unsigned long input_freq;
272
273static DEFINE_SPINLOCK(clk_doubler_lock);
274static DEFINE_SPINLOCK(clk_out_lock);
275static DEFINE_SPINLOCK(pll_div_lock);
276static DEFINE_SPINLOCK(cml_lock);
277static DEFINE_SPINLOCK(pll_d_lock);
278
279#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \
280 _clk_num, _regs, _gate_flags, _clk_id) \
281 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
282 30, 2, 0, 0, 8, 1, 0, _regs, _clk_num, \
283 periph_clk_enb_refcnt, _gate_flags, _clk_id)
284
285#define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
286 _clk_num, _regs, _gate_flags, _clk_id) \
287 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
288 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \
289 _regs, _clk_num, periph_clk_enb_refcnt, \
290 _gate_flags, _clk_id)
291
292#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
293 _clk_num, _regs, _gate_flags, _clk_id) \
294 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
295 29, 3, 0, 0, 8, 1, 0, _regs, _clk_num, \
296 periph_clk_enb_refcnt, _gate_flags, _clk_id)
297
298#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \
299 _clk_num, _regs, _gate_flags, _clk_id) \
300 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
301 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \
302 _clk_num, periph_clk_enb_refcnt, _gate_flags, \
303 _clk_id)
304
305#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
306 _clk_num, _regs, _clk_id) \
307 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
308 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs, \
309 _clk_num, periph_clk_enb_refcnt, 0, _clk_id)
310
311#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
312 _mux_shift, _mux_width, _clk_num, _regs, \
313 _gate_flags, _clk_id) \
314 TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
315 _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \
316 _clk_num, periph_clk_enb_refcnt, _gate_flags, \
317 _clk_id)
318
319/*
320 * IDs assigned here must be in sync with DT bindings definition
321 * for Tegra30 clocks.
322 */
323enum tegra30_clk {
324 cpu, rtc = 4, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, ndflash,
325 sdmmc1, sdmmc4, pwm = 17, i2s2, epp, gr2d = 21, usbd, isp, gr3d,
326 disp2 = 26, disp1, host1x, vcp, i2s0, cop_cache, mc, ahbdma, apbdma,
327 kbc = 36, statmon, pmc, kfuse = 40, sbc1, nor, sbc2 = 44, sbc3 = 46,
328 i2c5, dsia, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2,
329 usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3,
330 pcie, owr, afi, csite, pciex, avpucq, la, dtv = 79, ndspeed, i2c_slow,
331 dsib, irama = 84, iramb, iramc, iramd, cram2, audio_2x = 90, csus = 92,
332 cdev1, cdev2, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4,
333 i2c4, sbc5, sbc6, d_audio, apbif, dam0, dam1, dam2, hda2codec_2x,
334 atomics, audio0_2x, audio1_2x, audio2_2x, audio3_2x, audio4_2x,
335 spdif_2x, actmon, extern1, extern2, extern3, sata_oob, sata, hda, se,
336 hda2hdmi, sata_cold, uartb = 160, vfir, spdif_out, spdif_in, vi,
337 vi_sensor, fuse, fuse_burn, cve, tvo, clk_32k, clk_m, clk_m_div2,
338 clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_m, pll_m_out1, pll_p,
339 pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_a, pll_a_out0,
340 pll_d, pll_d_out0, pll_d2, pll_d2_out0, pll_u, pll_x, pll_x_out0, pll_e,
341 spdif_in_sync, i2s0_sync, i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync,
342 vimclk_sync, audio0, audio1, audio2, audio3, audio4, spdif, clk_out_1,
343 clk_out_2, clk_out_3, sclk, blink, cclk_g, cclk_lp, twd, cml0, cml1,
344 i2cslow, hclk, pclk, clk_out_1_mux = 300, clk_max
345};
346
347static struct clk *clks[clk_max];
348static struct clk_onecell_data clk_data;
349
350/*
351 * Structure defining the fields for USB UTMI clocks Parameters.
352 */
353struct utmi_clk_param {
354 /* Oscillator Frequency in KHz */
355 u32 osc_frequency;
356 /* UTMIP PLL Enable Delay Count */
357 u8 enable_delay_count;
358 /* UTMIP PLL Stable count */
359 u8 stable_count;
360 /* UTMIP PLL Active delay count */
361 u8 active_delay_count;
362 /* UTMIP PLL Xtal frequency count */
363 u8 xtal_freq_count;
364};
365
366static const struct utmi_clk_param utmi_parameters[] = {
367/* OSC_FREQUENCY, ENABLE_DLY, STABLE_CNT, ACTIVE_DLY, XTAL_FREQ_CNT */
368 {13000000, 0x02, 0x33, 0x05, 0x7F},
369 {19200000, 0x03, 0x4B, 0x06, 0xBB},
370 {12000000, 0x02, 0x2F, 0x04, 0x76},
371 {26000000, 0x04, 0x66, 0x09, 0xFE},
372 {16800000, 0x03, 0x41, 0x0A, 0xA4},
373};
374
375static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
376 { 12000000, 1040000000, 520, 6, 1, 8},
377 { 13000000, 1040000000, 480, 6, 1, 8},
378 { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */
379 { 19200000, 1040000000, 325, 6, 1, 6},
380 { 26000000, 1040000000, 520, 13, 1, 8},
381
382 { 12000000, 832000000, 416, 6, 1, 8},
383 { 13000000, 832000000, 832, 13, 1, 8},
384 { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */
385 { 19200000, 832000000, 260, 6, 1, 8},
386 { 26000000, 832000000, 416, 13, 1, 8},
387
388 { 12000000, 624000000, 624, 12, 1, 8},
389 { 13000000, 624000000, 624, 13, 1, 8},
390 { 16800000, 600000000, 520, 14, 1, 8},
391 { 19200000, 624000000, 520, 16, 1, 8},
392 { 26000000, 624000000, 624, 26, 1, 8},
393
394 { 12000000, 600000000, 600, 12, 1, 8},
395 { 13000000, 600000000, 600, 13, 1, 8},
396 { 16800000, 600000000, 500, 14, 1, 8},
397 { 19200000, 600000000, 375, 12, 1, 6},
398 { 26000000, 600000000, 600, 26, 1, 8},
399
400 { 12000000, 520000000, 520, 12, 1, 8},
401 { 13000000, 520000000, 520, 13, 1, 8},
402 { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */
403 { 19200000, 520000000, 325, 12, 1, 6},
404 { 26000000, 520000000, 520, 26, 1, 8},
405
406 { 12000000, 416000000, 416, 12, 1, 8},
407 { 13000000, 416000000, 416, 13, 1, 8},
408 { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */
409 { 19200000, 416000000, 260, 12, 1, 6},
410 { 26000000, 416000000, 416, 26, 1, 8},
411 { 0, 0, 0, 0, 0, 0 },
412};
413
414static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
415 { 12000000, 666000000, 666, 12, 1, 8},
416 { 13000000, 666000000, 666, 13, 1, 8},
417 { 16800000, 666000000, 555, 14, 1, 8},
418 { 19200000, 666000000, 555, 16, 1, 8},
419 { 26000000, 666000000, 666, 26, 1, 8},
420 { 12000000, 600000000, 600, 12, 1, 8},
421 { 13000000, 600000000, 600, 13, 1, 8},
422 { 16800000, 600000000, 500, 14, 1, 8},
423 { 19200000, 600000000, 375, 12, 1, 6},
424 { 26000000, 600000000, 600, 26, 1, 8},
425 { 0, 0, 0, 0, 0, 0 },
426};
427
428static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
429 { 12000000, 216000000, 432, 12, 2, 8},
430 { 13000000, 216000000, 432, 13, 2, 8},
431 { 16800000, 216000000, 360, 14, 2, 8},
432 { 19200000, 216000000, 360, 16, 2, 8},
433 { 26000000, 216000000, 432, 26, 2, 8},
434 { 0, 0, 0, 0, 0, 0 },
435};
436
437static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
438 { 9600000, 564480000, 294, 5, 1, 4},
439 { 9600000, 552960000, 288, 5, 1, 4},
440 { 9600000, 24000000, 5, 2, 1, 1},
441
442 { 28800000, 56448000, 49, 25, 1, 1},
443 { 28800000, 73728000, 64, 25, 1, 1},
444 { 28800000, 24000000, 5, 6, 1, 1},
445 { 0, 0, 0, 0, 0, 0 },
446};
447
448static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
449 { 12000000, 216000000, 216, 12, 1, 4},
450 { 13000000, 216000000, 216, 13, 1, 4},
451 { 16800000, 216000000, 180, 14, 1, 4},
452 { 19200000, 216000000, 180, 16, 1, 4},
453 { 26000000, 216000000, 216, 26, 1, 4},
454
455 { 12000000, 594000000, 594, 12, 1, 8},
456 { 13000000, 594000000, 594, 13, 1, 8},
457 { 16800000, 594000000, 495, 14, 1, 8},
458 { 19200000, 594000000, 495, 16, 1, 8},
459 { 26000000, 594000000, 594, 26, 1, 8},
460
461 { 12000000, 1000000000, 1000, 12, 1, 12},
462 { 13000000, 1000000000, 1000, 13, 1, 12},
463 { 19200000, 1000000000, 625, 12, 1, 8},
464 { 26000000, 1000000000, 1000, 26, 1, 12},
465
466 { 0, 0, 0, 0, 0, 0 },
467};
468
469static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
470 { 12000000, 480000000, 960, 12, 2, 12},
471 { 13000000, 480000000, 960, 13, 2, 12},
472 { 16800000, 480000000, 400, 7, 2, 5},
473 { 19200000, 480000000, 200, 4, 2, 3},
474 { 26000000, 480000000, 960, 26, 2, 12},
475 { 0, 0, 0, 0, 0, 0 },
476};
477
478static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
479 /* 1.7 GHz */
480 { 12000000, 1700000000, 850, 6, 1, 8},
481 { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */
482 { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */
483 { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */
484 { 26000000, 1700000000, 850, 13, 1, 8},
485
486 /* 1.6 GHz */
487 { 12000000, 1600000000, 800, 6, 1, 8},
488 { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */
489 { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */
490 { 19200000, 1600000000, 500, 6, 1, 8},
491 { 26000000, 1600000000, 800, 13, 1, 8},
492
493 /* 1.5 GHz */
494 { 12000000, 1500000000, 750, 6, 1, 8},
495 { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */
496 { 16800000, 1500000000, 625, 7, 1, 8},
497 { 19200000, 1500000000, 625, 8, 1, 8},
498 { 26000000, 1500000000, 750, 13, 1, 8},
499
500 /* 1.4 GHz */
501 { 12000000, 1400000000, 700, 6, 1, 8},
502 { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */
503 { 16800000, 1400000000, 1000, 12, 1, 8},
504 { 19200000, 1400000000, 875, 12, 1, 8},
505 { 26000000, 1400000000, 700, 13, 1, 8},
506
507 /* 1.3 GHz */
508 { 12000000, 1300000000, 975, 9, 1, 8},
509 { 13000000, 1300000000, 1000, 10, 1, 8},
510 { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */
511 { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */
512 { 26000000, 1300000000, 650, 13, 1, 8},
513
514 /* 1.2 GHz */
515 { 12000000, 1200000000, 1000, 10, 1, 8},
516 { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */
517 { 16800000, 1200000000, 1000, 14, 1, 8},
518 { 19200000, 1200000000, 1000, 16, 1, 8},
519 { 26000000, 1200000000, 600, 13, 1, 8},
520
521 /* 1.1 GHz */
522 { 12000000, 1100000000, 825, 9, 1, 8},
523 { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */
524 { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */
525 { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */
526 { 26000000, 1100000000, 550, 13, 1, 8},
527
528 /* 1 GHz */
529 { 12000000, 1000000000, 1000, 12, 1, 8},
530 { 13000000, 1000000000, 1000, 13, 1, 8},
531 { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */
532 { 19200000, 1000000000, 625, 12, 1, 8},
533 { 26000000, 1000000000, 1000, 26, 1, 8},
534
535 { 0, 0, 0, 0, 0, 0 },
536};
537
538static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
539 /* PLLE special case: use cpcon field to store cml divider value */
540 { 12000000, 100000000, 150, 1, 18, 11},
541 { 216000000, 100000000, 200, 18, 24, 13},
542 { 0, 0, 0, 0, 0, 0 },
543};
544
545/* PLL parameters */
546static struct tegra_clk_pll_params pll_c_params = {
547 .input_min = 2000000,
548 .input_max = 31000000,
549 .cf_min = 1000000,
550 .cf_max = 6000000,
551 .vco_min = 20000000,
552 .vco_max = 1400000000,
553 .base_reg = PLLC_BASE,
554 .misc_reg = PLLC_MISC,
555 .lock_bit_idx = PLL_BASE_LOCK,
556 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
557 .lock_delay = 300,
558};
559
560static struct tegra_clk_pll_params pll_m_params = {
561 .input_min = 2000000,
562 .input_max = 31000000,
563 .cf_min = 1000000,
564 .cf_max = 6000000,
565 .vco_min = 20000000,
566 .vco_max = 1200000000,
567 .base_reg = PLLM_BASE,
568 .misc_reg = PLLM_MISC,
569 .lock_bit_idx = PLL_BASE_LOCK,
570 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
571 .lock_delay = 300,
572};
573
574static struct tegra_clk_pll_params pll_p_params = {
575 .input_min = 2000000,
576 .input_max = 31000000,
577 .cf_min = 1000000,
578 .cf_max = 6000000,
579 .vco_min = 20000000,
580 .vco_max = 1400000000,
581 .base_reg = PLLP_BASE,
582 .misc_reg = PLLP_MISC,
583 .lock_bit_idx = PLL_BASE_LOCK,
584 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
585 .lock_delay = 300,
586};
587
588static struct tegra_clk_pll_params pll_a_params = {
589 .input_min = 2000000,
590 .input_max = 31000000,
591 .cf_min = 1000000,
592 .cf_max = 6000000,
593 .vco_min = 20000000,
594 .vco_max = 1400000000,
595 .base_reg = PLLA_BASE,
596 .misc_reg = PLLA_MISC,
597 .lock_bit_idx = PLL_BASE_LOCK,
598 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
599 .lock_delay = 300,
600};
601
602static struct tegra_clk_pll_params pll_d_params = {
603 .input_min = 2000000,
604 .input_max = 40000000,
605 .cf_min = 1000000,
606 .cf_max = 6000000,
607 .vco_min = 40000000,
608 .vco_max = 1000000000,
609 .base_reg = PLLD_BASE,
610 .misc_reg = PLLD_MISC,
611 .lock_bit_idx = PLL_BASE_LOCK,
612 .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
613 .lock_delay = 1000,
614};
615
616static struct tegra_clk_pll_params pll_d2_params = {
617 .input_min = 2000000,
618 .input_max = 40000000,
619 .cf_min = 1000000,
620 .cf_max = 6000000,
621 .vco_min = 40000000,
622 .vco_max = 1000000000,
623 .base_reg = PLLD2_BASE,
624 .misc_reg = PLLD2_MISC,
625 .lock_bit_idx = PLL_BASE_LOCK,
626 .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
627 .lock_delay = 1000,
628};
629
630static struct tegra_clk_pll_params pll_u_params = {
631 .input_min = 2000000,
632 .input_max = 40000000,
633 .cf_min = 1000000,
634 .cf_max = 6000000,
635 .vco_min = 48000000,
636 .vco_max = 960000000,
637 .base_reg = PLLU_BASE,
638 .misc_reg = PLLU_MISC,
639 .lock_bit_idx = PLL_BASE_LOCK,
640 .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
641 .lock_delay = 1000,
642};
643
644static struct tegra_clk_pll_params pll_x_params = {
645 .input_min = 2000000,
646 .input_max = 31000000,
647 .cf_min = 1000000,
648 .cf_max = 6000000,
649 .vco_min = 20000000,
650 .vco_max = 1700000000,
651 .base_reg = PLLX_BASE,
652 .misc_reg = PLLX_MISC,
653 .lock_bit_idx = PLL_BASE_LOCK,
654 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
655 .lock_delay = 300,
656};
657
658static struct tegra_clk_pll_params pll_e_params = {
659 .input_min = 12000000,
660 .input_max = 216000000,
661 .cf_min = 12000000,
662 .cf_max = 12000000,
663 .vco_min = 1200000000,
664 .vco_max = 2400000000U,
665 .base_reg = PLLE_BASE,
666 .misc_reg = PLLE_MISC,
667 .lock_bit_idx = PLLE_MISC_LOCK,
668 .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
669 .lock_delay = 300,
670};
671
672/* Peripheral clock registers */
673static struct tegra_clk_periph_regs periph_l_regs = {
674 .enb_reg = CLK_OUT_ENB_L,
675 .enb_set_reg = CLK_OUT_ENB_SET_L,
676 .enb_clr_reg = CLK_OUT_ENB_CLR_L,
677 .rst_reg = RST_DEVICES_L,
678 .rst_set_reg = RST_DEVICES_SET_L,
679 .rst_clr_reg = RST_DEVICES_CLR_L,
680};
681
682static struct tegra_clk_periph_regs periph_h_regs = {
683 .enb_reg = CLK_OUT_ENB_H,
684 .enb_set_reg = CLK_OUT_ENB_SET_H,
685 .enb_clr_reg = CLK_OUT_ENB_CLR_H,
686 .rst_reg = RST_DEVICES_H,
687 .rst_set_reg = RST_DEVICES_SET_H,
688 .rst_clr_reg = RST_DEVICES_CLR_H,
689};
690
691static struct tegra_clk_periph_regs periph_u_regs = {
692 .enb_reg = CLK_OUT_ENB_U,
693 .enb_set_reg = CLK_OUT_ENB_SET_U,
694 .enb_clr_reg = CLK_OUT_ENB_CLR_U,
695 .rst_reg = RST_DEVICES_U,
696 .rst_set_reg = RST_DEVICES_SET_U,
697 .rst_clr_reg = RST_DEVICES_CLR_U,
698};
699
700static struct tegra_clk_periph_regs periph_v_regs = {
701 .enb_reg = CLK_OUT_ENB_V,
702 .enb_set_reg = CLK_OUT_ENB_SET_V,
703 .enb_clr_reg = CLK_OUT_ENB_CLR_V,
704 .rst_reg = RST_DEVICES_V,
705 .rst_set_reg = RST_DEVICES_SET_V,
706 .rst_clr_reg = RST_DEVICES_CLR_V,
707};
708
709static struct tegra_clk_periph_regs periph_w_regs = {
710 .enb_reg = CLK_OUT_ENB_W,
711 .enb_set_reg = CLK_OUT_ENB_SET_W,
712 .enb_clr_reg = CLK_OUT_ENB_CLR_W,
713 .rst_reg = RST_DEVICES_W,
714 .rst_set_reg = RST_DEVICES_SET_W,
715 .rst_clr_reg = RST_DEVICES_CLR_W,
716};
717
718static void tegra30_clk_measure_input_freq(void)
719{
720 u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL);
721 u32 auto_clk_control = osc_ctrl & OSC_CTRL_OSC_FREQ_MASK;
722 u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
723
724 switch (auto_clk_control) {
725 case OSC_CTRL_OSC_FREQ_12MHZ:
726 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
727 input_freq = 12000000;
728 break;
729 case OSC_CTRL_OSC_FREQ_13MHZ:
730 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
731 input_freq = 13000000;
732 break;
733 case OSC_CTRL_OSC_FREQ_19_2MHZ:
734 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
735 input_freq = 19200000;
736 break;
737 case OSC_CTRL_OSC_FREQ_26MHZ:
738 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
739 input_freq = 26000000;
740 break;
741 case OSC_CTRL_OSC_FREQ_16_8MHZ:
742 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
743 input_freq = 16800000;
744 break;
745 case OSC_CTRL_OSC_FREQ_38_4MHZ:
746 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2);
747 input_freq = 38400000;
748 break;
749 case OSC_CTRL_OSC_FREQ_48MHZ:
750 BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4);
751 input_freq = 48000000;
752 break;
753 default:
754 pr_err("Unexpected auto clock control value %d",
755 auto_clk_control);
756 BUG();
757 return;
758 }
759}
760
761static unsigned int tegra30_get_pll_ref_div(void)
762{
763 u32 pll_ref_div = readl_relaxed(clk_base + OSC_CTRL) &
764 OSC_CTRL_PLL_REF_DIV_MASK;
765
766 switch (pll_ref_div) {
767 case OSC_CTRL_PLL_REF_DIV_1:
768 return 1;
769 case OSC_CTRL_PLL_REF_DIV_2:
770 return 2;
771 case OSC_CTRL_PLL_REF_DIV_4:
772 return 4;
773 default:
774 pr_err("Invalid pll ref divider %d", pll_ref_div);
775 BUG();
776 }
777 return 0;
778}
779
780static void tegra30_utmi_param_configure(void)
781{
782 u32 reg;
783 int i;
784
785 for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
786 if (input_freq == utmi_parameters[i].osc_frequency)
787 break;
788 }
789
790 if (i >= ARRAY_SIZE(utmi_parameters)) {
791 pr_err("%s: Unexpected input rate %lu\n", __func__, input_freq);
792 return;
793 }
794
795 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2);
796
797 /* Program UTMIP PLL stable and active counts */
798 reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
799 reg |= UTMIP_PLL_CFG2_STABLE_COUNT(
800 utmi_parameters[i].stable_count);
801
802 reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
803
804 reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(
805 utmi_parameters[i].active_delay_count);
806
807 /* Remove power downs from UTMIP PLL control bits */
808 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
809 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
810 reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
811
812 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2);
813
814 /* Program UTMIP PLL delay and oscillator frequency counts */
815 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
816 reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
817
818 reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(
819 utmi_parameters[i].enable_delay_count);
820
821 reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
822 reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(
823 utmi_parameters[i].xtal_freq_count);
824
825 /* Remove power downs from UTMIP PLL control bits */
826 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
827 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
828 reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
829
830 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
831}
832
833static const char *pll_e_parents[] = {"pll_ref", "pll_p"};
834
835static void __init tegra30_pll_init(void)
836{
837 struct clk *clk;
838
839 /* PLLC */
840 clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0,
841 0, &pll_c_params,
842 TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK,
843 pll_c_freq_table, NULL);
844 clk_register_clkdev(clk, "pll_c", NULL);
845 clks[pll_c] = clk;
846
847 /* PLLC_OUT1 */
848 clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
849 clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
850 8, 8, 1, NULL);
851 clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div",
852 clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT,
853 0, NULL);
854 clk_register_clkdev(clk, "pll_c_out1", NULL);
855 clks[pll_c_out1] = clk;
856
857 /* PLLP */
858 clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc_base, 0,
859 408000000, &pll_p_params,
860 TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON |
861 TEGRA_PLL_USE_LOCK, pll_p_freq_table, NULL);
862 clk_register_clkdev(clk, "pll_p", NULL);
863 clks[pll_p] = clk;
864
865 /* PLLP_OUT1 */
866 clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p",
867 clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED |
868 TEGRA_DIVIDER_ROUND_UP, 8, 8, 1,
869 &pll_div_lock);
870 clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div",
871 clk_base + PLLP_OUTA, 1, 0,
872 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
873 &pll_div_lock);
874 clk_register_clkdev(clk, "pll_p_out1", NULL);
875 clks[pll_p_out1] = clk;
876
877 /* PLLP_OUT2 */
878 clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p",
879 clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED |
880 TEGRA_DIVIDER_ROUND_UP, 24, 8, 1,
881 &pll_div_lock);
882 clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div",
883 clk_base + PLLP_OUTA, 17, 16,
884 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
885 &pll_div_lock);
886 clk_register_clkdev(clk, "pll_p_out2", NULL);
887 clks[pll_p_out2] = clk;
888
889 /* PLLP_OUT3 */
890 clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p",
891 clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED |
892 TEGRA_DIVIDER_ROUND_UP, 8, 8, 1,
893 &pll_div_lock);
894 clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div",
895 clk_base + PLLP_OUTB, 1, 0,
896 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
897 &pll_div_lock);
898 clk_register_clkdev(clk, "pll_p_out3", NULL);
899 clks[pll_p_out3] = clk;
900
901 /* PLLP_OUT4 */
902 clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p",
903 clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED |
904 TEGRA_DIVIDER_ROUND_UP, 24, 8, 1,
905 &pll_div_lock);
906 clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div",
907 clk_base + PLLP_OUTB, 17, 16,
908 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
909 &pll_div_lock);
910 clk_register_clkdev(clk, "pll_p_out4", NULL);
911 clks[pll_p_out4] = clk;
912
913 /* PLLM */
914 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
915 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0,
916 &pll_m_params, TEGRA_PLLM | TEGRA_PLL_HAS_CPCON |
917 TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK,
918 pll_m_freq_table, NULL);
919 clk_register_clkdev(clk, "pll_m", NULL);
920 clks[pll_m] = clk;
921
922 /* PLLM_OUT1 */
923 clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m",
924 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
925 8, 8, 1, NULL);
926 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
927 clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED |
928 CLK_SET_RATE_PARENT, 0, NULL);
929 clk_register_clkdev(clk, "pll_m_out1", NULL);
930 clks[pll_m_out1] = clk;
931
932 /* PLLX */
933 clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0,
934 0, &pll_x_params, TEGRA_PLL_HAS_CPCON |
935 TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK,
936 pll_x_freq_table, NULL);
937 clk_register_clkdev(clk, "pll_x", NULL);
938 clks[pll_x] = clk;
939
940 /* PLLX_OUT0 */
941 clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x",
942 CLK_SET_RATE_PARENT, 1, 2);
943 clk_register_clkdev(clk, "pll_x_out0", NULL);
944 clks[pll_x_out0] = clk;
945
946 /* PLLU */
947 clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc_base, 0,
948 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON |
949 TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK,
950 pll_u_freq_table,
951 NULL);
952 clk_register_clkdev(clk, "pll_u", NULL);
953 clks[pll_u] = clk;
954
955 tegra30_utmi_param_configure();
956
957 /* PLLD */
958 clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0,
959 0, &pll_d_params, TEGRA_PLL_HAS_CPCON |
960 TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK,
961 pll_d_freq_table, &pll_d_lock);
962 clk_register_clkdev(clk, "pll_d", NULL);
963 clks[pll_d] = clk;
964
965 /* PLLD_OUT0 */
966 clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d",
967 CLK_SET_RATE_PARENT, 1, 2);
968 clk_register_clkdev(clk, "pll_d_out0", NULL);
969 clks[pll_d_out0] = clk;
970
971 /* PLLD2 */
972 clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0,
973 0, &pll_d2_params, TEGRA_PLL_HAS_CPCON |
974 TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK,
975 pll_d_freq_table, NULL);
976 clk_register_clkdev(clk, "pll_d2", NULL);
977 clks[pll_d2] = clk;
978
979 /* PLLD2_OUT0 */
980 clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2",
981 CLK_SET_RATE_PARENT, 1, 2);
982 clk_register_clkdev(clk, "pll_d2_out0", NULL);
983 clks[pll_d2_out0] = clk;
984
985 /* PLLA */
986 clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc_base,
987 0, 0, &pll_a_params, TEGRA_PLL_HAS_CPCON |
988 TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL);
989 clk_register_clkdev(clk, "pll_a", NULL);
990 clks[pll_a] = clk;
991
992 /* PLLA_OUT0 */
993 clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a",
994 clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
995 8, 8, 1, NULL);
996 clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div",
997 clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED |
998 CLK_SET_RATE_PARENT, 0, NULL);
999 clk_register_clkdev(clk, "pll_a_out0", NULL);
1000 clks[pll_a_out0] = clk;
1001
1002 /* PLLE */
1003 clk = clk_register_mux(NULL, "pll_e_mux", pll_e_parents,
1004 ARRAY_SIZE(pll_e_parents), 0,
1005 clk_base + PLLE_AUX, 2, 1, 0, NULL);
1006 clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base,
1007 CLK_GET_RATE_NOCACHE, 100000000, &pll_e_params,
1008 TEGRA_PLLE_CONFIGURE, pll_e_freq_table, NULL);
1009 clk_register_clkdev(clk, "pll_e", NULL);
1010 clks[pll_e] = clk;
1011}
1012
1013static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync",
1014 "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",};
1015static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
1016 "clk_m_div4", "extern1", };
1017static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
1018 "clk_m_div4", "extern2", };
1019static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
1020 "clk_m_div4", "extern3", };
1021
1022static void __init tegra30_audio_clk_init(void)
1023{
1024 struct clk *clk;
1025
1026 /* spdif_in_sync */
1027 clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000,
1028 24000000);
1029 clk_register_clkdev(clk, "spdif_in_sync", NULL);
1030 clks[spdif_in_sync] = clk;
1031
1032 /* i2s0_sync */
1033 clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000);
1034 clk_register_clkdev(clk, "i2s0_sync", NULL);
1035 clks[i2s0_sync] = clk;
1036
1037 /* i2s1_sync */
1038 clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000);
1039 clk_register_clkdev(clk, "i2s1_sync", NULL);
1040 clks[i2s1_sync] = clk;
1041
1042 /* i2s2_sync */
1043 clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000);
1044 clk_register_clkdev(clk, "i2s2_sync", NULL);
1045 clks[i2s2_sync] = clk;
1046
1047 /* i2s3_sync */
1048 clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000);
1049 clk_register_clkdev(clk, "i2s3_sync", NULL);
1050 clks[i2s3_sync] = clk;
1051
1052 /* i2s4_sync */
1053 clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000);
1054 clk_register_clkdev(clk, "i2s4_sync", NULL);
1055 clks[i2s4_sync] = clk;
1056
1057 /* vimclk_sync */
1058 clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000);
1059 clk_register_clkdev(clk, "vimclk_sync", NULL);
1060 clks[vimclk_sync] = clk;
1061
1062 /* audio0 */
1063 clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk,
1064 ARRAY_SIZE(mux_audio_sync_clk), 0,
1065 clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, NULL);
1066 clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0,
1067 clk_base + AUDIO_SYNC_CLK_I2S0, 4,
1068 CLK_GATE_SET_TO_DISABLE, NULL);
1069 clk_register_clkdev(clk, "audio0", NULL);
1070 clks[audio0] = clk;
1071
1072 /* audio1 */
1073 clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk,
1074 ARRAY_SIZE(mux_audio_sync_clk), 0,
1075 clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, NULL);
1076 clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0,
1077 clk_base + AUDIO_SYNC_CLK_I2S1, 4,
1078 CLK_GATE_SET_TO_DISABLE, NULL);
1079 clk_register_clkdev(clk, "audio1", NULL);
1080 clks[audio1] = clk;
1081
1082 /* audio2 */
1083 clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk,
1084 ARRAY_SIZE(mux_audio_sync_clk), 0,
1085 clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, NULL);
1086 clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0,
1087 clk_base + AUDIO_SYNC_CLK_I2S2, 4,
1088 CLK_GATE_SET_TO_DISABLE, NULL);
1089 clk_register_clkdev(clk, "audio2", NULL);
1090 clks[audio2] = clk;
1091
1092 /* audio3 */
1093 clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk,
1094 ARRAY_SIZE(mux_audio_sync_clk), 0,
1095 clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, NULL);
1096 clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0,
1097 clk_base + AUDIO_SYNC_CLK_I2S3, 4,
1098 CLK_GATE_SET_TO_DISABLE, NULL);
1099 clk_register_clkdev(clk, "audio3", NULL);
1100 clks[audio3] = clk;
1101
1102 /* audio4 */
1103 clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk,
1104 ARRAY_SIZE(mux_audio_sync_clk), 0,
1105 clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, NULL);
1106 clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0,
1107 clk_base + AUDIO_SYNC_CLK_I2S4, 4,
1108 CLK_GATE_SET_TO_DISABLE, NULL);
1109 clk_register_clkdev(clk, "audio4", NULL);
1110 clks[audio4] = clk;
1111
1112 /* spdif */
1113 clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk,
1114 ARRAY_SIZE(mux_audio_sync_clk), 0,
1115 clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, NULL);
1116 clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0,
1117 clk_base + AUDIO_SYNC_CLK_SPDIF, 4,
1118 CLK_GATE_SET_TO_DISABLE, NULL);
1119 clk_register_clkdev(clk, "spdif", NULL);
1120 clks[spdif] = clk;
1121
1122 /* audio0_2x */
1123 clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0",
1124 CLK_SET_RATE_PARENT, 2, 1);
1125 clk = tegra_clk_register_divider("audio0_div", "audio0_doubler",
1126 clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, 0,
1127 &clk_doubler_lock);
1128 clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div",
1129 TEGRA_PERIPH_NO_RESET, clk_base,
1130 CLK_SET_RATE_PARENT, 113, &periph_v_regs,
1131 periph_clk_enb_refcnt);
1132 clk_register_clkdev(clk, "audio0_2x", NULL);
1133 clks[audio0_2x] = clk;
1134
1135 /* audio1_2x */
1136 clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1",
1137 CLK_SET_RATE_PARENT, 2, 1);
1138 clk = tegra_clk_register_divider("audio1_div", "audio1_doubler",
1139 clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, 0,
1140 &clk_doubler_lock);
1141 clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div",
1142 TEGRA_PERIPH_NO_RESET, clk_base,
1143 CLK_SET_RATE_PARENT, 114, &periph_v_regs,
1144 periph_clk_enb_refcnt);
1145 clk_register_clkdev(clk, "audio1_2x", NULL);
1146 clks[audio1_2x] = clk;
1147
1148 /* audio2_2x */
1149 clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2",
1150 CLK_SET_RATE_PARENT, 2, 1);
1151 clk = tegra_clk_register_divider("audio2_div", "audio2_doubler",
1152 clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, 0,
1153 &clk_doubler_lock);
1154 clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div",
1155 TEGRA_PERIPH_NO_RESET, clk_base,
1156 CLK_SET_RATE_PARENT, 115, &periph_v_regs,
1157 periph_clk_enb_refcnt);
1158 clk_register_clkdev(clk, "audio2_2x", NULL);
1159 clks[audio2_2x] = clk;
1160
1161 /* audio3_2x */
1162 clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3",
1163 CLK_SET_RATE_PARENT, 2, 1);
1164 clk = tegra_clk_register_divider("audio3_div", "audio3_doubler",
1165 clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, 0,
1166 &clk_doubler_lock);
1167 clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div",
1168 TEGRA_PERIPH_NO_RESET, clk_base,
1169 CLK_SET_RATE_PARENT, 116, &periph_v_regs,
1170 periph_clk_enb_refcnt);
1171 clk_register_clkdev(clk, "audio3_2x", NULL);
1172 clks[audio3_2x] = clk;
1173
1174 /* audio4_2x */
1175 clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4",
1176 CLK_SET_RATE_PARENT, 2, 1);
1177 clk = tegra_clk_register_divider("audio4_div", "audio4_doubler",
1178 clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, 0,
1179 &clk_doubler_lock);
1180 clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div",
1181 TEGRA_PERIPH_NO_RESET, clk_base,
1182 CLK_SET_RATE_PARENT, 117, &periph_v_regs,
1183 periph_clk_enb_refcnt);
1184 clk_register_clkdev(clk, "audio4_2x", NULL);
1185 clks[audio4_2x] = clk;
1186
1187 /* spdif_2x */
1188 clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif",
1189 CLK_SET_RATE_PARENT, 2, 1);
1190 clk = tegra_clk_register_divider("spdif_div", "spdif_doubler",
1191 clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, 0,
1192 &clk_doubler_lock);
1193 clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div",
1194 TEGRA_PERIPH_NO_RESET, clk_base,
1195 CLK_SET_RATE_PARENT, 118, &periph_v_regs,
1196 periph_clk_enb_refcnt);
1197 clk_register_clkdev(clk, "spdif_2x", NULL);
1198 clks[spdif_2x] = clk;
1199}
1200
1201static void __init tegra30_pmc_clk_init(void)
1202{
1203 struct clk *clk;
1204
1205 /* clk_out_1 */
1206 clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents,
1207 ARRAY_SIZE(clk_out1_parents), 0,
1208 pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0,
1209 &clk_out_lock);
1210 clks[clk_out_1_mux] = clk;
1211 clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0,
1212 pmc_base + PMC_CLK_OUT_CNTRL, 2, 0,
1213 &clk_out_lock);
1214 clk_register_clkdev(clk, "extern1", "clk_out_1");
1215 clks[clk_out_1] = clk;
1216
1217 /* clk_out_2 */
1218 clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents,
1219 ARRAY_SIZE(clk_out1_parents), 0,
1220 pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0,
1221 &clk_out_lock);
1222 clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0,
1223 pmc_base + PMC_CLK_OUT_CNTRL, 10, 0,
1224 &clk_out_lock);
1225 clk_register_clkdev(clk, "extern2", "clk_out_2");
1226 clks[clk_out_2] = clk;
1227
1228 /* clk_out_3 */
1229 clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents,
1230 ARRAY_SIZE(clk_out1_parents), 0,
1231 pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0,
1232 &clk_out_lock);
1233 clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0,
1234 pmc_base + PMC_CLK_OUT_CNTRL, 18, 0,
1235 &clk_out_lock);
1236 clk_register_clkdev(clk, "extern3", "clk_out_3");
1237 clks[clk_out_3] = clk;
1238
1239 /* blink */
1240 writel_relaxed(0, pmc_base + PMC_BLINK_TIMER);
1241 clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0,
1242 pmc_base + PMC_DPD_PADS_ORIDE,
1243 PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL);
1244 clk = clk_register_gate(NULL, "blink", "blink_override", 0,
1245 pmc_base + PMC_CTRL,
1246 PMC_CTRL_BLINK_ENB, 0, NULL);
1247 clk_register_clkdev(clk, "blink", NULL);
1248 clks[blink] = clk;
1249
1250}
1251
1252const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
1253 "pll_p_cclkg", "pll_p_out4_cclkg",
1254 "pll_p_out3_cclkg", "unused", "pll_x" };
1255const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
1256 "pll_p_cclklp", "pll_p_out4_cclklp",
1257 "pll_p_out3_cclklp", "unused", "pll_x",
1258 "pll_x_out0" };
1259const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
1260 "pll_p_out3", "pll_p_out2", "unused",
1261 "clk_32k", "pll_m_out1" };
1262
1263static void __init tegra30_super_clk_init(void)
1264{
1265 struct clk *clk;
1266
1267 /*
1268 * Clock input to cclk_g divided from pll_p using
1269 * U71 divider of cclk_g.
1270 */
1271 clk = tegra_clk_register_divider("pll_p_cclkg", "pll_p",
1272 clk_base + SUPER_CCLKG_DIVIDER, 0,
1273 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
1274 clk_register_clkdev(clk, "pll_p_cclkg", NULL);
1275
1276 /*
1277 * Clock input to cclk_g divided from pll_p_out3 using
1278 * U71 divider of cclk_g.
1279 */
1280 clk = tegra_clk_register_divider("pll_p_out3_cclkg", "pll_p_out3",
1281 clk_base + SUPER_CCLKG_DIVIDER, 0,
1282 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
1283 clk_register_clkdev(clk, "pll_p_out3_cclkg", NULL);
1284
1285 /*
1286 * Clock input to cclk_g divided from pll_p_out4 using
1287 * U71 divider of cclk_g.
1288 */
1289 clk = tegra_clk_register_divider("pll_p_out4_cclkg", "pll_p_out4",
1290 clk_base + SUPER_CCLKG_DIVIDER, 0,
1291 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
1292 clk_register_clkdev(clk, "pll_p_out4_cclkg", NULL);
1293
1294 /* CCLKG */
1295 clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents,
1296 ARRAY_SIZE(cclk_g_parents),
1297 CLK_SET_RATE_PARENT,
1298 clk_base + CCLKG_BURST_POLICY,
1299 0, 4, 0, 0, NULL);
1300 clk_register_clkdev(clk, "cclk_g", NULL);
1301 clks[cclk_g] = clk;
1302
1303 /*
1304 * Clock input to cclk_lp divided from pll_p using
1305 * U71 divider of cclk_lp.
1306 */
1307 clk = tegra_clk_register_divider("pll_p_cclklp", "pll_p",
1308 clk_base + SUPER_CCLKLP_DIVIDER, 0,
1309 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
1310 clk_register_clkdev(clk, "pll_p_cclklp", NULL);
1311
1312 /*
1313 * Clock input to cclk_lp divided from pll_p_out3 using
1314 * U71 divider of cclk_lp.
1315 */
1316 clk = tegra_clk_register_divider("pll_p_out3_cclklp", "pll_p_out3",
1317 clk_base + SUPER_CCLKG_DIVIDER, 0,
1318 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
1319 clk_register_clkdev(clk, "pll_p_out3_cclklp", NULL);
1320
1321 /*
1322 * Clock input to cclk_lp divided from pll_p_out4 using
1323 * U71 divider of cclk_lp.
1324 */
1325 clk = tegra_clk_register_divider("pll_p_out4_cclklp", "pll_p_out4",
1326 clk_base + SUPER_CCLKLP_DIVIDER, 0,
1327 TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
1328 clk_register_clkdev(clk, "pll_p_out4_cclklp", NULL);
1329
1330 /* CCLKLP */
1331 clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents,
1332 ARRAY_SIZE(cclk_lp_parents),
1333 CLK_SET_RATE_PARENT,
1334 clk_base + CCLKLP_BURST_POLICY,
1335 TEGRA_DIVIDER_2, 4, 8, 9,
1336 NULL);
1337 clk_register_clkdev(clk, "cclk_lp", NULL);
1338 clks[cclk_lp] = clk;
1339
1340 /* SCLK */
1341 clk = tegra_clk_register_super_mux("sclk", sclk_parents,
1342 ARRAY_SIZE(sclk_parents),
1343 CLK_SET_RATE_PARENT,
1344 clk_base + SCLK_BURST_POLICY,
1345 0, 4, 0, 0, NULL);
1346 clk_register_clkdev(clk, "sclk", NULL);
1347 clks[sclk] = clk;
1348
1349 /* HCLK */
1350 clk = clk_register_divider(NULL, "hclk_div", "sclk", 0,
1351 clk_base + SYSTEM_CLK_RATE, 4, 2, 0, NULL);
1352 clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT,
1353 clk_base + SYSTEM_CLK_RATE, 7,
1354 CLK_GATE_SET_TO_DISABLE, NULL);
1355 clk_register_clkdev(clk, "hclk", NULL);
1356 clks[hclk] = clk;
1357
1358 /* PCLK */
1359 clk = clk_register_divider(NULL, "pclk_div", "hclk", 0,
1360 clk_base + SYSTEM_CLK_RATE, 0, 2, 0, NULL);
1361 clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT,
1362 clk_base + SYSTEM_CLK_RATE, 3,
1363 CLK_GATE_SET_TO_DISABLE, NULL);
1364 clk_register_clkdev(clk, "pclk", NULL);
1365 clks[pclk] = clk;
1366
1367 /* twd */
1368 clk = clk_register_fixed_factor(NULL, "twd", "cclk_g",
1369 CLK_SET_RATE_PARENT, 1, 2);
1370 clk_register_clkdev(clk, "twd", NULL);
1371 clks[twd] = clk;
1372}
1373
1374static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p",
1375 "clk_m" };
1376static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" };
1377static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" };
1378static const char *i2s0_parents[] = { "pll_a_out0", "audio0_2x", "pll_p",
1379 "clk_m" };
1380static const char *i2s1_parents[] = { "pll_a_out0", "audio1_2x", "pll_p",
1381 "clk_m" };
1382static const char *i2s2_parents[] = { "pll_a_out0", "audio2_2x", "pll_p",
1383 "clk_m" };
1384static const char *i2s3_parents[] = { "pll_a_out0", "audio3_2x", "pll_p",
1385 "clk_m" };
1386static const char *i2s4_parents[] = { "pll_a_out0", "audio4_2x", "pll_p",
1387 "clk_m" };
1388static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p",
1389 "clk_m" };
1390static const char *spdif_in_parents[] = { "pll_p", "pll_c", "pll_m" };
1391static const char *mux_pllpc_clk32k_clkm[] = { "pll_p", "pll_c", "clk_32k",
1392 "clk_m" };
1393static const char *mux_pllpc_clkm_clk32k[] = { "pll_p", "pll_c", "clk_m",
1394 "clk_32k" };
1395static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" };
1396static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c",
1397 "clk_m" };
1398static const char *mux_pllp_clkm[] = { "pll_p", "unused", "unused", "clk_m" };
1399static const char *mux_pllpmdacd2_clkm[] = { "pll_p", "pll_m", "pll_d_out0",
1400 "pll_a_out0", "pll_c",
1401 "pll_d2_out0", "clk_m" };
1402static const char *mux_plla_clk32k_pllp_clkm_plle[] = { "pll_a_out0",
1403 "clk_32k", "pll_p",
1404 "clk_m", "pll_e" };
1405static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0",
1406 "pll_d2_out0" };
1407
1408static struct tegra_periph_init_data tegra_periph_clk_list[] = {
1409 TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", i2s0_parents, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0),
1410 TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1),
1411 TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2),
1412 TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", i2s3_parents, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3),
1413 TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", i2s4_parents, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4),
1414 TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out),
1415 TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in),
1416 TEGRA_INIT_DATA_MUX("d_audio", "d_audio", "tegra30-ahub", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, 0, d_audio),
1417 TEGRA_INIT_DATA_MUX("dam0", NULL, "tegra30-dam.0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, &periph_v_regs, 0, dam0),
1418 TEGRA_INIT_DATA_MUX("dam1", NULL, "tegra30-dam.1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, &periph_v_regs, 0, dam1),
1419 TEGRA_INIT_DATA_MUX("dam2", NULL, "tegra30-dam.2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, &periph_v_regs, 0, dam2),
1420 TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, 0, hda),
1421 TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, 0, hda2codec_2x),
1422 TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1),
1423 TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2),
1424 TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3),
1425 TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4),
1426 TEGRA_INIT_DATA_MUX("sbc5", NULL, "spi_tegra.4", mux_pllpcm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5),
1427 TEGRA_INIT_DATA_MUX("sbc6", NULL, "spi_tegra.5", mux_pllpcm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6),
1428 TEGRA_INIT_DATA_MUX("sata_oob", NULL, "tegra_sata_oob", mux_pllpcm_clkm, CLK_SOURCE_SATA_OOB, 123, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata_oob),
1429 TEGRA_INIT_DATA_MUX("sata", NULL, "tegra_sata", mux_pllpcm_clkm, CLK_SOURCE_SATA, 124, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata),
1430 TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, TEGRA_PERIPH_ON_APB, ndflash),
1431 TEGRA_INIT_DATA_MUX("ndspeed", NULL, "tegra_nand_speed", mux_pllpcm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed),
1432 TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir),
1433 TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite),
1434 TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la),
1435 TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr),
1436 TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi),
1437 TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllpc_clkm_clk32k, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor),
1438 TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllpc_clk32k_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow),
1439 TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde),
1440 TEGRA_INIT_DATA_INT("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi),
1441 TEGRA_INIT_DATA_INT("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp),
1442 TEGRA_INIT_DATA_INT("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe),
1443 TEGRA_INIT_DATA_INT("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x),
1444 TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d),
1445 TEGRA_INIT_DATA_INT("3d2", NULL, "3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, &periph_v_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d2),
1446 TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d),
1447 TEGRA_INIT_DATA_INT("se", NULL, "se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, 0, se),
1448 TEGRA_INIT_DATA_MUX("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect),
1449 TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor),
1450 TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1),
1451 TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2),
1452 TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3),
1453 TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4),
1454 TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve),
1455 TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo),
1456 TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac),
1457 TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllpc_clk32k_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon),
1458 TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor),
1459 TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1),
1460 TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2),
1461 TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3),
1462 TEGRA_INIT_DATA_DIV16("i2c4", "div-clk", "tegra-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2c4),
1463 TEGRA_INIT_DATA_DIV16("i2c5", "div-clk", "tegra-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c5),
1464 TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta),
1465 TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb),
1466 TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc),
1467 TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd),
1468 TEGRA_INIT_DATA_UART("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 66, &periph_u_regs, uarte),
1469 TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi),
1470 TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1),
1471 TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2),
1472 TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3),
1473 TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, 0, pwm),
1474};
1475
1476static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
1477 TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP1, 29, 3, 27, &periph_l_regs, 0, disp1),
1478 TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP2, 29, 3, 26, &periph_l_regs, 0, disp2),
1479 TEGRA_INIT_DATA_NODIV("dsib", NULL, "tegradc.1", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, &periph_u_regs, 0, dsib),
1480};
1481
1482static void __init tegra30_periph_clk_init(void)
1483{
1484 struct tegra_periph_init_data *data;
1485 struct clk *clk;
1486 int i;
1487
1488 /* apbdma */
1489 clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, 0, 34,
1490 &periph_h_regs, periph_clk_enb_refcnt);
1491 clk_register_clkdev(clk, NULL, "tegra-apbdma");
1492 clks[apbdma] = clk;
1493
1494 /* rtc */
1495 clk = tegra_clk_register_periph_gate("rtc", "clk_32k",
1496 TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB,
1497 clk_base, 0, 4, &periph_l_regs,
1498 periph_clk_enb_refcnt);
1499 clk_register_clkdev(clk, NULL, "rtc-tegra");
1500 clks[rtc] = clk;
1501
1502 /* timer */
1503 clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, 0,
1504 5, &periph_l_regs, periph_clk_enb_refcnt);
1505 clk_register_clkdev(clk, NULL, "timer");
1506 clks[timer] = clk;
1507
1508 /* kbc */
1509 clk = tegra_clk_register_periph_gate("kbc", "clk_32k",
1510 TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB,
1511 clk_base, 0, 36, &periph_h_regs,
1512 periph_clk_enb_refcnt);
1513 clk_register_clkdev(clk, NULL, "tegra-kbc");
1514 clks[kbc] = clk;
1515
1516 /* csus */
1517 clk = tegra_clk_register_periph_gate("csus", "clk_m",
1518 TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB,
1519 clk_base, 0, 92, &periph_u_regs,
1520 periph_clk_enb_refcnt);
1521 clk_register_clkdev(clk, "csus", "tengra_camera");
1522 clks[csus] = clk;
1523
1524 /* vcp */
1525 clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, 29,
1526 &periph_l_regs, periph_clk_enb_refcnt);
1527 clk_register_clkdev(clk, "vcp", "tegra-avp");
1528 clks[vcp] = clk;
1529
1530 /* bsea */
1531 clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, 0,
1532 62, &periph_h_regs, periph_clk_enb_refcnt);
1533 clk_register_clkdev(clk, "bsea", "tegra-avp");
1534 clks[bsea] = clk;
1535
1536 /* bsev */
1537 clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, 0,
1538 63, &periph_h_regs, periph_clk_enb_refcnt);
1539 clk_register_clkdev(clk, "bsev", "tegra-aes");
1540 clks[bsev] = clk;
1541
1542 /* usbd */
1543 clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0,
1544 22, &periph_l_regs, periph_clk_enb_refcnt);
1545 clk_register_clkdev(clk, NULL, "fsl-tegra-udc");
1546 clks[usbd] = clk;
1547
1548 /* usb2 */
1549 clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0,
1550 58, &periph_h_regs, periph_clk_enb_refcnt);
1551 clk_register_clkdev(clk, NULL, "tegra-ehci.1");
1552 clks[usb2] = clk;
1553
1554 /* usb3 */
1555 clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0,
1556 59, &periph_h_regs, periph_clk_enb_refcnt);
1557 clk_register_clkdev(clk, NULL, "tegra-ehci.2");
1558 clks[usb3] = clk;
1559
1560 /* dsia */
1561 clk = tegra_clk_register_periph_gate("dsia", "pll_d_out0", 0, clk_base,
1562 0, 48, &periph_h_regs,
1563 periph_clk_enb_refcnt);
1564 clk_register_clkdev(clk, "dsia", "tegradc.0");
1565 clks[dsia] = clk;
1566
1567 /* csi */
1568 clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base,
1569 0, 52, &periph_h_regs,
1570 periph_clk_enb_refcnt);
1571 clk_register_clkdev(clk, "csi", "tegra_camera");
1572 clks[csi] = clk;
1573
1574 /* isp */
1575 clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23,
1576 &periph_l_regs, periph_clk_enb_refcnt);
1577 clk_register_clkdev(clk, "isp", "tegra_camera");
1578 clks[isp] = clk;
1579
1580 /* pcie */
1581 clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0,
1582 70, &periph_u_regs, periph_clk_enb_refcnt);
1583 clk_register_clkdev(clk, "pcie", "tegra-pcie");
1584 clks[pcie] = clk;
1585
1586 /* afi */
1587 clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72,
1588 &periph_u_regs, periph_clk_enb_refcnt);
1589 clk_register_clkdev(clk, "afi", "tegra-pcie");
1590 clks[afi] = clk;
1591
1592 /* kfuse */
1593 clk = tegra_clk_register_periph_gate("kfuse", "clk_m",
1594 TEGRA_PERIPH_ON_APB,
1595 clk_base, 0, 40, &periph_h_regs,
1596 periph_clk_enb_refcnt);
1597 clk_register_clkdev(clk, NULL, "kfuse-tegra");
1598 clks[kfuse] = clk;
1599
1600 /* fuse */
1601 clk = tegra_clk_register_periph_gate("fuse", "clk_m",
1602 TEGRA_PERIPH_ON_APB,
1603 clk_base, 0, 39, &periph_h_regs,
1604 periph_clk_enb_refcnt);
1605 clk_register_clkdev(clk, "fuse", "fuse-tegra");
1606 clks[fuse] = clk;
1607
1608 /* fuse_burn */
1609 clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m",
1610 TEGRA_PERIPH_ON_APB,
1611 clk_base, 0, 39, &periph_h_regs,
1612 periph_clk_enb_refcnt);
1613 clk_register_clkdev(clk, "fuse_burn", "fuse-tegra");
1614 clks[fuse_burn] = clk;
1615
1616 /* apbif */
1617 clk = tegra_clk_register_periph_gate("apbif", "clk_m", 0,
1618 clk_base, 0, 107, &periph_v_regs,
1619 periph_clk_enb_refcnt);
1620 clk_register_clkdev(clk, "apbif", "tegra30-ahub");
1621 clks[apbif] = clk;
1622
1623 /* hda2hdmi */
1624 clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m",
1625 TEGRA_PERIPH_ON_APB,
1626 clk_base, 0, 128, &periph_w_regs,
1627 periph_clk_enb_refcnt);
1628 clk_register_clkdev(clk, "hda2hdmi", "tegra30-hda");
1629 clks[hda2hdmi] = clk;
1630
1631 /* sata_cold */
1632 clk = tegra_clk_register_periph_gate("sata_cold", "clk_m",
1633 TEGRA_PERIPH_ON_APB,
1634 clk_base, 0, 129, &periph_w_regs,
1635 periph_clk_enb_refcnt);
1636 clk_register_clkdev(clk, NULL, "tegra_sata_cold");
1637 clks[sata_cold] = clk;
1638
1639 /* dtv */
1640 clk = tegra_clk_register_periph_gate("dtv", "clk_m",
1641 TEGRA_PERIPH_ON_APB,
1642 clk_base, 0, 79, &periph_u_regs,
1643 periph_clk_enb_refcnt);
1644 clk_register_clkdev(clk, NULL, "dtv");
1645 clks[dtv] = clk;
1646
1647 /* emc */
1648 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
1649 ARRAY_SIZE(mux_pllmcp_clkm), 0,
1650 clk_base + CLK_SOURCE_EMC,
1651 30, 2, 0, NULL);
1652 clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
1653 57, &periph_h_regs, periph_clk_enb_refcnt);
1654 clk_register_clkdev(clk, "emc", NULL);
1655 clks[emc] = clk;
1656
1657 for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
1658 data = &tegra_periph_clk_list[i];
1659 clk = tegra_clk_register_periph(data->name, data->parent_names,
1660 data->num_parents, &data->periph,
1661 clk_base, data->offset);
1662 clk_register_clkdev(clk, data->con_id, data->dev_id);
1663 clks[data->clk_id] = clk;
1664 }
1665
1666 for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) {
1667 data = &tegra_periph_nodiv_clk_list[i];
1668 clk = tegra_clk_register_periph_nodiv(data->name,
1669 data->parent_names,
1670 data->num_parents, &data->periph,
1671 clk_base, data->offset);
1672 clk_register_clkdev(clk, data->con_id, data->dev_id);
1673 clks[data->clk_id] = clk;
1674 }
1675}
1676
1677static void __init tegra30_fixed_clk_init(void)
1678{
1679 struct clk *clk;
1680
1681 /* clk_32k */
1682 clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT,
1683 32768);
1684 clk_register_clkdev(clk, "clk_32k", NULL);
1685 clks[clk_32k] = clk;
1686
1687 /* clk_m_div2 */
1688 clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m",
1689 CLK_SET_RATE_PARENT, 1, 2);
1690 clk_register_clkdev(clk, "clk_m_div2", NULL);
1691 clks[clk_m_div2] = clk;
1692
1693 /* clk_m_div4 */
1694 clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m",
1695 CLK_SET_RATE_PARENT, 1, 4);
1696 clk_register_clkdev(clk, "clk_m_div4", NULL);
1697 clks[clk_m_div4] = clk;
1698
1699 /* cml0 */
1700 clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX,
1701 0, 0, &cml_lock);
1702 clk_register_clkdev(clk, "cml0", NULL);
1703 clks[cml0] = clk;
1704
1705 /* cml1 */
1706 clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX,
1707 1, 0, &cml_lock);
1708 clk_register_clkdev(clk, "cml1", NULL);
1709 clks[cml1] = clk;
1710
1711 /* pciex */
1712 clk = clk_register_fixed_rate(NULL, "pciex", "pll_e", 0, 100000000);
1713 clk_register_clkdev(clk, "pciex", NULL);
1714 clks[pciex] = clk;
1715}
1716
1717static void __init tegra30_osc_clk_init(void)
1718{
1719 struct clk *clk;
1720 unsigned int pll_ref_div;
1721
1722 tegra30_clk_measure_input_freq();
1723
1724 /* clk_m */
1725 clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT,
1726 input_freq);
1727 clk_register_clkdev(clk, "clk_m", NULL);
1728 clks[clk_m] = clk;
1729
1730 /* pll_ref */
1731 pll_ref_div = tegra30_get_pll_ref_div();
1732 clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m",
1733 CLK_SET_RATE_PARENT, 1, pll_ref_div);
1734 clk_register_clkdev(clk, "pll_ref", NULL);
1735 clks[pll_ref] = clk;
1736}
1737
1738/* Tegra30 CPU clock and reset control functions */
1739static void tegra30_wait_cpu_in_reset(u32 cpu)
1740{
1741 unsigned int reg;
1742
1743 do {
1744 reg = readl(clk_base +
1745 TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
1746 cpu_relax();
1747 } while (!(reg & (1 << cpu))); /* check CPU been reset or not */
1748
1749 return;
1750}
1751
1752static void tegra30_put_cpu_in_reset(u32 cpu)
1753{
1754 writel(CPU_RESET(cpu),
1755 clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
1756 dmb();
1757}
1758
1759static void tegra30_cpu_out_of_reset(u32 cpu)
1760{
1761 writel(CPU_RESET(cpu),
1762 clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
1763 wmb();
1764}
1765
1766
1767static void tegra30_enable_cpu_clock(u32 cpu)
1768{
1769 unsigned int reg;
1770
1771 writel(CPU_CLOCK(cpu),
1772 clk_base + TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR);
1773 reg = readl(clk_base +
1774 TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR);
1775}
1776
1777static void tegra30_disable_cpu_clock(u32 cpu)
1778{
1779
1780 unsigned int reg;
1781
1782 reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1783 writel(reg | CPU_CLOCK(cpu),
1784 clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
1785}
1786
1787#ifdef CONFIG_PM_SLEEP
1788static bool tegra30_cpu_rail_off_ready(void)
1789{
1790 unsigned int cpu_rst_status;
1791 int cpu_pwr_status;
1792
1793 cpu_rst_status = readl(clk_base +
1794 TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
1795 cpu_pwr_status = tegra_powergate_is_powered(TEGRA_POWERGATE_CPU1) ||
1796 tegra_powergate_is_powered(TEGRA_POWERGATE_CPU2) ||
1797 tegra_powergate_is_powered(TEGRA_POWERGATE_CPU3);
1798
1799 if (((cpu_rst_status & 0xE) != 0xE) || cpu_pwr_status)
1800 return false;
1801
1802 return true;
1803}
1804
1805static void tegra30_cpu_clock_suspend(void)
1806{
1807 /* switch coresite to clk_m, save off original source */
1808 tegra30_cpu_clk_sctx.clk_csite_src =
1809 readl(clk_base + CLK_RESET_SOURCE_CSITE);
1810 writel(3<<30, clk_base + CLK_RESET_SOURCE_CSITE);
1811
1812 tegra30_cpu_clk_sctx.cpu_burst =
1813 readl(clk_base + CLK_RESET_CCLK_BURST);
1814 tegra30_cpu_clk_sctx.pllx_base =
1815 readl(clk_base + CLK_RESET_PLLX_BASE);
1816 tegra30_cpu_clk_sctx.pllx_misc =
1817 readl(clk_base + CLK_RESET_PLLX_MISC);
1818 tegra30_cpu_clk_sctx.cclk_divider =
1819 readl(clk_base + CLK_RESET_CCLK_DIVIDER);
1820}
1821
1822static void tegra30_cpu_clock_resume(void)
1823{
1824 unsigned int reg, policy;
1825
1826 /* Is CPU complex already running on PLLX? */
1827 reg = readl(clk_base + CLK_RESET_CCLK_BURST);
1828 policy = (reg >> CLK_RESET_CCLK_BURST_POLICY_SHIFT) & 0xF;
1829
1830 if (policy == CLK_RESET_CCLK_IDLE_POLICY)
1831 reg = (reg >> CLK_RESET_CCLK_IDLE_POLICY_SHIFT) & 0xF;
1832 else if (policy == CLK_RESET_CCLK_RUN_POLICY)
1833 reg = (reg >> CLK_RESET_CCLK_RUN_POLICY_SHIFT) & 0xF;
1834 else
1835 BUG();
1836
1837 if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) {
1838 /* restore PLLX settings if CPU is on different PLL */
1839 writel(tegra30_cpu_clk_sctx.pllx_misc,
1840 clk_base + CLK_RESET_PLLX_MISC);
1841 writel(tegra30_cpu_clk_sctx.pllx_base,
1842 clk_base + CLK_RESET_PLLX_BASE);
1843
1844 /* wait for PLL stabilization if PLLX was enabled */
1845 if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30))
1846 udelay(300);
1847 }
1848
1849 /*
1850 * Restore original burst policy setting for calls resulting from CPU
1851 * LP2 in idle or system suspend.
1852 */
1853 writel(tegra30_cpu_clk_sctx.cclk_divider,
1854 clk_base + CLK_RESET_CCLK_DIVIDER);
1855 writel(tegra30_cpu_clk_sctx.cpu_burst,
1856 clk_base + CLK_RESET_CCLK_BURST);
1857
1858 writel(tegra30_cpu_clk_sctx.clk_csite_src,
1859 clk_base + CLK_RESET_SOURCE_CSITE);
1860}
1861#endif
1862
1863static struct tegra_cpu_car_ops tegra30_cpu_car_ops = {
1864 .wait_for_reset = tegra30_wait_cpu_in_reset,
1865 .put_in_reset = tegra30_put_cpu_in_reset,
1866 .out_of_reset = tegra30_cpu_out_of_reset,
1867 .enable_clock = tegra30_enable_cpu_clock,
1868 .disable_clock = tegra30_disable_cpu_clock,
1869#ifdef CONFIG_PM_SLEEP
1870 .rail_off_ready = tegra30_cpu_rail_off_ready,
1871 .suspend = tegra30_cpu_clock_suspend,
1872 .resume = tegra30_cpu_clock_resume,
1873#endif
1874};
1875
1876static __initdata struct tegra_clk_init_table init_table[] = {
1877 {uarta, pll_p, 408000000, 1},
1878 {pll_a, clk_max, 564480000, 1},
1879 {pll_a_out0, clk_max, 11289600, 1},
1880 {extern1, pll_a_out0, 0, 1},
1881 {clk_out_1_mux, extern1, 0, 0},
1882 {clk_out_1, clk_max, 0, 1},
1883 {blink, clk_max, 0, 1},
1884 {i2s0, pll_a_out0, 11289600, 0},
1885 {i2s1, pll_a_out0, 11289600, 0},
1886 {i2s2, pll_a_out0, 11289600, 0},
1887 {i2s3, pll_a_out0, 11289600, 0},
1888 {i2s4, pll_a_out0, 11289600, 0},
1889 {sdmmc1, pll_p, 48000000, 0},
1890 {sdmmc2, pll_p, 48000000, 0},
1891 {sdmmc3, pll_p, 48000000, 0},
1892 {pll_m, clk_max, 0, 1},
1893 {pclk, clk_max, 0, 1},
1894 {csite, clk_max, 0, 1},
1895 {emc, clk_max, 0, 1},
1896 {mselect, clk_max, 0, 1},
1897 {sbc1, pll_p, 100000000, 0},
1898 {sbc2, pll_p, 100000000, 0},
1899 {sbc3, pll_p, 100000000, 0},
1900 {sbc4, pll_p, 100000000, 0},
1901 {sbc5, pll_p, 100000000, 0},
1902 {sbc6, pll_p, 100000000, 0},
1903 {host1x, pll_c, 150000000, 0},
1904 {disp1, pll_p, 600000000, 0},
1905 {disp2, pll_p, 600000000, 0},
1906 {twd, clk_max, 0, 1},
1907 {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */
1908};
1909
1910/*
1911 * Some clocks may be used by different drivers depending on the board
1912 * configuration. List those here to register them twice in the clock lookup
1913 * table under two names.
1914 */
1915static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
1916 TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL),
1917 TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL),
1918 TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL),
1919 TEGRA_CLK_DUPLICATE(bsev, "tegra-avp", "bsev"),
1920 TEGRA_CLK_DUPLICATE(bsev, "nvavp", "bsev"),
1921 TEGRA_CLK_DUPLICATE(vde, "tegra-aes", "vde"),
1922 TEGRA_CLK_DUPLICATE(bsea, "tegra-aes", "bsea"),
1923 TEGRA_CLK_DUPLICATE(bsea, "nvavp", "bsea"),
1924 TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL),
1925 TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"),
1926 TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"),
1927 TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL),
1928 TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"),
1929 TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */
1930};
1931
1932static const struct of_device_id pmc_match[] __initconst = {
1933 { .compatible = "nvidia,tegra30-pmc" },
1934 {},
1935};
1936
1937void __init tegra30_clock_init(struct device_node *np)
1938{
1939 struct device_node *node;
1940 int i;
1941
1942 clk_base = of_iomap(np, 0);
1943 if (!clk_base) {
1944 pr_err("ioremap tegra30 CAR failed\n");
1945 return;
1946 }
1947
1948 node = of_find_matching_node(NULL, pmc_match);
1949 if (!node) {
1950 pr_err("Failed to find pmc node\n");
1951 BUG();
1952 }
1953
1954 pmc_base = of_iomap(node, 0);
1955 if (!pmc_base) {
1956 pr_err("Can't map pmc registers\n");
1957 BUG();
1958 }
1959
1960 tegra30_osc_clk_init();
1961 tegra30_fixed_clk_init();
1962 tegra30_pll_init();
1963 tegra30_super_clk_init();
1964 tegra30_periph_clk_init();
1965 tegra30_audio_clk_init();
1966 tegra30_pmc_clk_init();
1967
1968 for (i = 0; i < ARRAY_SIZE(clks); i++) {
1969 if (IS_ERR(clks[i])) {
1970 pr_err("Tegra30 clk %d: register failed with %ld\n",
1971 i, PTR_ERR(clks[i]));
1972 BUG();
1973 }
1974 if (!clks[i])
1975 clks[i] = ERR_PTR(-EINVAL);
1976 }
1977
1978 tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max);
1979
1980 clk_data.clks = clks;
1981 clk_data.clk_num = ARRAY_SIZE(clks);
1982 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1983
1984 tegra_init_from_table(init_table, clks, clk_max);
1985
1986 tegra_cpu_car_ops = &tegra30_cpu_car_ops;
1987}
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
new file mode 100644
index 000000000000..a603b9af0ad3
--- /dev/null
+++ b/drivers/clk/tegra/clk.c
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/clk.h>
18#include <linux/clk-provider.h>
19#include <linux/of.h>
20#include <linux/clk/tegra.h>
21
22#include "clk.h"
23
24/* Global data of Tegra CPU CAR ops */
25struct tegra_cpu_car_ops *tegra_cpu_car_ops;
26
27void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
28 struct clk *clks[], int clk_max)
29{
30 struct clk *clk;
31
32 for (; dup_list->clk_id < clk_max; dup_list++) {
33 clk = clks[dup_list->clk_id];
34 dup_list->lookup.clk = clk;
35 clkdev_add(&dup_list->lookup);
36 }
37}
38
39void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
40 struct clk *clks[], int clk_max)
41{
42 struct clk *clk;
43
44 for (; tbl->clk_id < clk_max; tbl++) {
45 clk = clks[tbl->clk_id];
46 if (IS_ERR_OR_NULL(clk))
47 return;
48
49 if (tbl->parent_id < clk_max) {
50 struct clk *parent = clks[tbl->parent_id];
51 if (clk_set_parent(clk, parent)) {
52 pr_err("%s: Failed to set parent %s of %s\n",
53 __func__, __clk_get_name(parent),
54 __clk_get_name(clk));
55 WARN_ON(1);
56 }
57 }
58
59 if (tbl->rate)
60 if (clk_set_rate(clk, tbl->rate)) {
61 pr_err("%s: Failed to set rate %lu of %s\n",
62 __func__, tbl->rate,
63 __clk_get_name(clk));
64 WARN_ON(1);
65 }
66
67 if (tbl->state)
68 if (clk_prepare_enable(clk)) {
69 pr_err("%s: Failed to enable %s\n", __func__,
70 __clk_get_name(clk));
71 WARN_ON(1);
72 }
73 }
74}
75
76static const struct of_device_id tegra_dt_clk_match[] = {
77 { .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init },
78 { .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init },
79 { }
80};
81
82void __init tegra_clocks_init(void)
83{
84 of_clk_init(tegra_dt_clk_match);
85}
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
new file mode 100644
index 000000000000..0744731c6229
--- /dev/null
+++ b/drivers/clk/tegra/clk.h
@@ -0,0 +1,502 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __TEGRA_CLK_H
18#define __TEGRA_CLK_H
19
20#include <linux/clk-provider.h>
21#include <linux/clkdev.h>
22
23/**
24 * struct tegra_clk_sync_source - external clock source from codec
25 *
26 * @hw: handle between common and hardware-specific interfaces
27 * @rate: input frequency from source
28 * @max_rate: max rate allowed
29 */
30struct tegra_clk_sync_source {
31 struct clk_hw hw;
32 unsigned long rate;
33 unsigned long max_rate;
34};
35
36#define to_clk_sync_source(_hw) \
37 container_of(_hw, struct tegra_clk_sync_source, hw)
38
39extern const struct clk_ops tegra_clk_sync_source_ops;
40struct clk *tegra_clk_register_sync_source(const char *name,
41 unsigned long fixed_rate, unsigned long max_rate);
42
43/**
44 * struct tegra_clk_frac_div - fractional divider clock
45 *
46 * @hw: handle between common and hardware-specific interfaces
47 * @reg: register containing divider
48 * @flags: hardware-specific flags
49 * @shift: shift to the divider bit field
50 * @width: width of the divider bit field
51 * @frac_width: width of the fractional bit field
52 * @lock: register lock
53 *
54 * Flags:
55 * TEGRA_DIVIDER_ROUND_UP - This flags indicates to round up the divider value.
56 * TEGRA_DIVIDER_FIXED - Fixed rate PLL dividers has addition override bit, this
57 * flag indicates that this divider is for fixed rate PLL.
58 * TEGRA_DIVIDER_INT - Some modules can not cope with the duty cycle when
59 * fraction bit is set. This flags indicates to calculate divider for which
60 * fracton bit will be zero.
61 * TEGRA_DIVIDER_UART - UART module divider has additional enable bit which is
62 * set when divider value is not 0. This flags indicates that the divider
63 * is for UART module.
64 */
65struct tegra_clk_frac_div {
66 struct clk_hw hw;
67 void __iomem *reg;
68 u8 flags;
69 u8 shift;
70 u8 width;
71 u8 frac_width;
72 spinlock_t *lock;
73};
74
75#define to_clk_frac_div(_hw) container_of(_hw, struct tegra_clk_frac_div, hw)
76
77#define TEGRA_DIVIDER_ROUND_UP BIT(0)
78#define TEGRA_DIVIDER_FIXED BIT(1)
79#define TEGRA_DIVIDER_INT BIT(2)
80#define TEGRA_DIVIDER_UART BIT(3)
81
82extern const struct clk_ops tegra_clk_frac_div_ops;
83struct clk *tegra_clk_register_divider(const char *name,
84 const char *parent_name, void __iomem *reg,
85 unsigned long flags, u8 clk_divider_flags, u8 shift, u8 width,
86 u8 frac_width, spinlock_t *lock);
87
88/*
89 * Tegra PLL:
90 *
91 * In general, there are 3 requirements for each PLL
92 * that SW needs to be comply with.
93 * (1) Input frequency range (REF).
94 * (2) Comparison frequency range (CF). CF = REF/DIVM.
95 * (3) VCO frequency range (VCO). VCO = CF * DIVN.
96 *
97 * The final PLL output frequency (FO) = VCO >> DIVP.
98 */
99
100/**
101 * struct tegra_clk_pll_freq_table - PLL frequecy table
102 *
103 * @input_rate: input rate from source
104 * @output_rate: output rate from PLL for the input rate
105 * @n: feedback divider
106 * @m: input divider
107 * @p: post divider
108 * @cpcon: charge pump current
109 */
110struct tegra_clk_pll_freq_table {
111 unsigned long input_rate;
112 unsigned long output_rate;
113 u16 n;
114 u16 m;
115 u8 p;
116 u8 cpcon;
117};
118
119/**
120 * struct clk_pll_params - PLL parameters
121 *
122 * @input_min: Minimum input frequency
123 * @input_max: Maximum input frequency
124 * @cf_min: Minimum comparison frequency
125 * @cf_max: Maximum comparison frequency
126 * @vco_min: Minimum VCO frequency
127 * @vco_max: Maximum VCO frequency
128 * @base_reg: PLL base reg offset
129 * @misc_reg: PLL misc reg offset
130 * @lock_reg: PLL lock reg offset
131 * @lock_bit_idx: Bit index for PLL lock status
132 * @lock_enable_bit_idx: Bit index to enable PLL lock
133 * @lock_delay: Delay in us if PLL lock is not used
134 */
135struct tegra_clk_pll_params {
136 unsigned long input_min;
137 unsigned long input_max;
138 unsigned long cf_min;
139 unsigned long cf_max;
140 unsigned long vco_min;
141 unsigned long vco_max;
142
143 u32 base_reg;
144 u32 misc_reg;
145 u32 lock_reg;
146 u32 lock_bit_idx;
147 u32 lock_enable_bit_idx;
148 int lock_delay;
149};
150
151/**
152 * struct tegra_clk_pll - Tegra PLL clock
153 *
154 * @hw: handle between common and hardware-specifix interfaces
155 * @clk_base: address of CAR controller
156 * @pmc: address of PMC, required to read override bits
157 * @freq_table: array of frequencies supported by PLL
158 * @params: PLL parameters
159 * @flags: PLL flags
160 * @fixed_rate: PLL rate if it is fixed
161 * @lock: register lock
162 * @divn_shift: shift to the feedback divider bit field
163 * @divn_width: width of the feedback divider bit field
164 * @divm_shift: shift to the input divider bit field
165 * @divm_width: width of the input divider bit field
166 * @divp_shift: shift to the post divider bit field
167 * @divp_width: width of the post divider bit field
168 *
169 * Flags:
170 * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
171 * PLL locking. If not set it will use lock_delay value to wait.
172 * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
173 * to be programmed to change output frequency of the PLL.
174 * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
175 * to be programmed to change output frequency of the PLL.
176 * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
177 * to be programmed to change output frequency of the PLL.
178 * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
179 * that it is PLLU and invert post divider value.
180 * TEGRA_PLLM - PLLM has additional override settings in PMC. This
181 * flag indicates that it is PLLM and use override settings.
182 * TEGRA_PLL_FIXED - We are not supposed to change output frequency
183 * of some plls.
184 * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
185 */
186struct tegra_clk_pll {
187 struct clk_hw hw;
188 void __iomem *clk_base;
189 void __iomem *pmc;
190 u8 flags;
191 unsigned long fixed_rate;
192 spinlock_t *lock;
193 u8 divn_shift;
194 u8 divn_width;
195 u8 divm_shift;
196 u8 divm_width;
197 u8 divp_shift;
198 u8 divp_width;
199 struct tegra_clk_pll_freq_table *freq_table;
200 struct tegra_clk_pll_params *params;
201};
202
203#define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
204
205#define TEGRA_PLL_USE_LOCK BIT(0)
206#define TEGRA_PLL_HAS_CPCON BIT(1)
207#define TEGRA_PLL_SET_LFCON BIT(2)
208#define TEGRA_PLL_SET_DCCON BIT(3)
209#define TEGRA_PLLU BIT(4)
210#define TEGRA_PLLM BIT(5)
211#define TEGRA_PLL_FIXED BIT(6)
212#define TEGRA_PLLE_CONFIGURE BIT(7)
213
214extern const struct clk_ops tegra_clk_pll_ops;
215extern const struct clk_ops tegra_clk_plle_ops;
216struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
217 void __iomem *clk_base, void __iomem *pmc,
218 unsigned long flags, unsigned long fixed_rate,
219 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
220 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
221struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
222 void __iomem *clk_base, void __iomem *pmc,
223 unsigned long flags, unsigned long fixed_rate,
224 struct tegra_clk_pll_params *pll_params, u8 pll_flags,
225 struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
226
227/**
228 * struct tegra_clk_pll_out - PLL divider down clock
229 *
230 * @hw: handle between common and hardware-specific interfaces
231 * @reg: register containing the PLL divider
232 * @enb_bit_idx: bit to enable/disable PLL divider
233 * @rst_bit_idx: bit to reset PLL divider
234 * @lock: register lock
235 * @flags: hardware-specific flags
236 */
237struct tegra_clk_pll_out {
238 struct clk_hw hw;
239 void __iomem *reg;
240 u8 enb_bit_idx;
241 u8 rst_bit_idx;
242 spinlock_t *lock;
243 u8 flags;
244};
245
246#define to_clk_pll_out(_hw) container_of(_hw, struct tegra_clk_pll_out, hw)
247
248extern const struct clk_ops tegra_clk_pll_out_ops;
249struct clk *tegra_clk_register_pll_out(const char *name,
250 const char *parent_name, void __iomem *reg, u8 enb_bit_idx,
251 u8 rst_bit_idx, unsigned long flags, u8 pll_div_flags,
252 spinlock_t *lock);
253
254/**
255 * struct tegra_clk_periph_regs - Registers controlling peripheral clock
256 *
257 * @enb_reg: read the enable status
258 * @enb_set_reg: write 1 to enable clock
259 * @enb_clr_reg: write 1 to disable clock
260 * @rst_reg: read the reset status
261 * @rst_set_reg: write 1 to assert the reset of peripheral
262 * @rst_clr_reg: write 1 to deassert the reset of peripheral
263 */
264struct tegra_clk_periph_regs {
265 u32 enb_reg;
266 u32 enb_set_reg;
267 u32 enb_clr_reg;
268 u32 rst_reg;
269 u32 rst_set_reg;
270 u32 rst_clr_reg;
271};
272
273/**
274 * struct tegra_clk_periph_gate - peripheral gate clock
275 *
276 * @magic: magic number to validate type
277 * @hw: handle between common and hardware-specific interfaces
278 * @clk_base: address of CAR controller
279 * @regs: Registers to control the peripheral
280 * @flags: hardware-specific flags
281 * @clk_num: Clock number
282 * @enable_refcnt: array to maintain reference count of the clock
283 *
284 * Flags:
285 * TEGRA_PERIPH_NO_RESET - This flag indicates that reset is not allowed
286 * for this module.
287 * TEGRA_PERIPH_MANUAL_RESET - This flag indicates not to reset module
288 * after clock enable and driver for the module is responsible for
289 * doing reset.
290 * TEGRA_PERIPH_ON_APB - If peripheral is in the APB bus then read the
291 * bus to flush the write operation in apb bus. This flag indicates
292 * that this peripheral is in apb bus.
293 */
294struct tegra_clk_periph_gate {
295 u32 magic;
296 struct clk_hw hw;
297 void __iomem *clk_base;
298 u8 flags;
299 int clk_num;
300 int *enable_refcnt;
301 struct tegra_clk_periph_regs *regs;
302};
303
304#define to_clk_periph_gate(_hw) \
305 container_of(_hw, struct tegra_clk_periph_gate, hw)
306
307#define TEGRA_CLK_PERIPH_GATE_MAGIC 0x17760309
308
309#define TEGRA_PERIPH_NO_RESET BIT(0)
310#define TEGRA_PERIPH_MANUAL_RESET BIT(1)
311#define TEGRA_PERIPH_ON_APB BIT(2)
312
313void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert);
314extern const struct clk_ops tegra_clk_periph_gate_ops;
315struct clk *tegra_clk_register_periph_gate(const char *name,
316 const char *parent_name, u8 gate_flags, void __iomem *clk_base,
317 unsigned long flags, int clk_num,
318 struct tegra_clk_periph_regs *pregs, int *enable_refcnt);
319
320/**
321 * struct clk-periph - peripheral clock
322 *
323 * @magic: magic number to validate type
324 * @hw: handle between common and hardware-specific interfaces
325 * @mux: mux clock
326 * @divider: divider clock
327 * @gate: gate clock
328 * @mux_ops: mux clock ops
329 * @div_ops: divider clock ops
330 * @gate_ops: gate clock ops
331 */
332struct tegra_clk_periph {
333 u32 magic;
334 struct clk_hw hw;
335 struct clk_mux mux;
336 struct tegra_clk_frac_div divider;
337 struct tegra_clk_periph_gate gate;
338
339 const struct clk_ops *mux_ops;
340 const struct clk_ops *div_ops;
341 const struct clk_ops *gate_ops;
342};
343
344#define to_clk_periph(_hw) container_of(_hw, struct tegra_clk_periph, hw)
345
346#define TEGRA_CLK_PERIPH_MAGIC 0x18221223
347
348extern const struct clk_ops tegra_clk_periph_ops;
349struct clk *tegra_clk_register_periph(const char *name,
350 const char **parent_names, int num_parents,
351 struct tegra_clk_periph *periph, void __iomem *clk_base,
352 u32 offset);
353struct clk *tegra_clk_register_periph_nodiv(const char *name,
354 const char **parent_names, int num_parents,
355 struct tegra_clk_periph *periph, void __iomem *clk_base,
356 u32 offset);
357
358#define TEGRA_CLK_PERIPH(_mux_shift, _mux_width, _mux_flags, \
359 _div_shift, _div_width, _div_frac_width, \
360 _div_flags, _clk_num, _enb_refcnt, _regs, \
361 _gate_flags) \
362 { \
363 .mux = { \
364 .flags = _mux_flags, \
365 .shift = _mux_shift, \
366 .width = _mux_width, \
367 }, \
368 .divider = { \
369 .flags = _div_flags, \
370 .shift = _div_shift, \
371 .width = _div_width, \
372 .frac_width = _div_frac_width, \
373 }, \
374 .gate = { \
375 .flags = _gate_flags, \
376 .clk_num = _clk_num, \
377 .enable_refcnt = _enb_refcnt, \
378 .regs = _regs, \
379 }, \
380 .mux_ops = &clk_mux_ops, \
381 .div_ops = &tegra_clk_frac_div_ops, \
382 .gate_ops = &tegra_clk_periph_gate_ops, \
383 }
384
385struct tegra_periph_init_data {
386 const char *name;
387 int clk_id;
388 const char **parent_names;
389 int num_parents;
390 struct tegra_clk_periph periph;
391 u32 offset;
392 const char *con_id;
393 const char *dev_id;
394};
395
396#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset, \
397 _mux_shift, _mux_width, _mux_flags, _div_shift, \
398 _div_width, _div_frac_width, _div_flags, _regs, \
399 _clk_num, _enb_refcnt, _gate_flags, _clk_id) \
400 { \
401 .name = _name, \
402 .clk_id = _clk_id, \
403 .parent_names = _parent_names, \
404 .num_parents = ARRAY_SIZE(_parent_names), \
405 .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_width, \
406 _mux_flags, _div_shift, \
407 _div_width, _div_frac_width, \
408 _div_flags, _clk_num, \
409 _enb_refcnt, _regs, \
410 _gate_flags), \
411 .offset = _offset, \
412 .con_id = _con_id, \
413 .dev_id = _dev_id, \
414 }
415
416/**
417 * struct clk_super_mux - super clock
418 *
419 * @hw: handle between common and hardware-specific interfaces
420 * @reg: register controlling multiplexer
421 * @width: width of the multiplexer bit field
422 * @flags: hardware-specific flags
423 * @div2_index: bit controlling divide-by-2
424 * @pllx_index: PLLX index in the parent list
425 * @lock: register lock
426 *
427 * Flags:
428 * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
429 * that this is LP cluster clock.
430 */
431struct tegra_clk_super_mux {
432 struct clk_hw hw;
433 void __iomem *reg;
434 u8 width;
435 u8 flags;
436 u8 div2_index;
437 u8 pllx_index;
438 spinlock_t *lock;
439};
440
441#define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw)
442
443#define TEGRA_DIVIDER_2 BIT(0)
444
445extern const struct clk_ops tegra_clk_super_ops;
446struct clk *tegra_clk_register_super_mux(const char *name,
447 const char **parent_names, u8 num_parents,
448 unsigned long flags, void __iomem *reg, u8 clk_super_flags,
449 u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock);
450
451/**
452 * struct clk_init_tabel - clock initialization table
453 * @clk_id: clock id as mentioned in device tree bindings
454 * @parent_id: parent clock id as mentioned in device tree bindings
455 * @rate: rate to set
456 * @state: enable/disable
457 */
458struct tegra_clk_init_table {
459 unsigned int clk_id;
460 unsigned int parent_id;
461 unsigned long rate;
462 int state;
463};
464
465/**
466 * struct clk_duplicate - duplicate clocks
467 * @clk_id: clock id as mentioned in device tree bindings
468 * @lookup: duplicate lookup entry for the clock
469 */
470struct tegra_clk_duplicate {
471 int clk_id;
472 struct clk_lookup lookup;
473};
474
475#define TEGRA_CLK_DUPLICATE(_clk_id, _dev, _con) \
476 { \
477 .clk_id = _clk_id, \
478 .lookup = { \
479 .dev_id = _dev, \
480 .con_id = _con, \
481 }, \
482 }
483
484void tegra_init_from_table(struct tegra_clk_init_table *tbl,
485 struct clk *clks[], int clk_max);
486
487void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
488 struct clk *clks[], int clk_max);
489
490#ifdef CONFIG_ARCH_TEGRA_2x_SOC
491void tegra20_clock_init(struct device_node *np);
492#else
493static inline void tegra20_clock_init(struct device_node *np) {}
494#endif /* CONFIG_ARCH_TEGRA_2x_SOC */
495
496#ifdef CONFIG_ARCH_TEGRA_3x_SOC
497void tegra30_clock_init(struct device_node *np);
498#else
499static inline void tegra30_clock_init(struct device_node *np) {}
500#endif /* CONFIG_ARCH_TEGRA_3x_SOC */
501
502#endif /* TEGRA_CLK_H */
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index c4cc27e5c8a5..071e2c3eec4f 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -39,4 +39,10 @@ config CPU_IDLE_CALXEDA
39 help 39 help
40 Select this to enable cpuidle on Calxeda processors. 40 Select this to enable cpuidle on Calxeda processors.
41 41
42config CPU_IDLE_KIRKWOOD
43 bool "CPU Idle Driver for Kirkwood processors"
44 depends on ARCH_KIRKWOOD
45 help
46 Select this to enable cpuidle on Kirkwood processors.
47
42endif 48endif
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 03ee87482c71..24c6e7d945ed 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -6,3 +6,4 @@ obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
6obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o 6obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
7 7
8obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o 8obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
9obj-$(CONFIG_CPU_IDLE_KIRKWOOD) += cpuidle-kirkwood.o
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/drivers/cpuidle/cpuidle-kirkwood.c
index f7304670f2f8..670aa1e55cd6 100644
--- a/arch/arm/mach-kirkwood/cpuidle.c
+++ b/drivers/cpuidle/cpuidle-kirkwood.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/module.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
19#include <linux/cpuidle.h> 20#include <linux/cpuidle.h>
@@ -21,16 +22,17 @@
21#include <linux/export.h> 22#include <linux/export.h>
22#include <asm/proc-fns.h> 23#include <asm/proc-fns.h>
23#include <asm/cpuidle.h> 24#include <asm/cpuidle.h>
24#include <mach/kirkwood.h>
25 25
26#define KIRKWOOD_MAX_STATES 2 26#define KIRKWOOD_MAX_STATES 2
27 27
28static void __iomem *ddr_operation_base;
29
28/* Actual code that puts the SoC in different idle states */ 30/* Actual code that puts the SoC in different idle states */
29static int kirkwood_enter_idle(struct cpuidle_device *dev, 31static int kirkwood_enter_idle(struct cpuidle_device *dev,
30 struct cpuidle_driver *drv, 32 struct cpuidle_driver *drv,
31 int index) 33 int index)
32{ 34{
33 writel(0x7, DDR_OPERATION_BASE); 35 writel(0x7, ddr_operation_base);
34 cpu_do_idle(); 36 cpu_do_idle();
35 37
36 return index; 38 return index;
@@ -51,13 +53,22 @@ static struct cpuidle_driver kirkwood_idle_driver = {
51 }, 53 },
52 .state_count = KIRKWOOD_MAX_STATES, 54 .state_count = KIRKWOOD_MAX_STATES,
53}; 55};
56static struct cpuidle_device *device;
54 57
55static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); 58static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
56 59
57/* Initialize CPU idle by registering the idle states */ 60/* Initialize CPU idle by registering the idle states */
58static int kirkwood_init_cpuidle(void) 61static int kirkwood_cpuidle_probe(struct platform_device *pdev)
59{ 62{
60 struct cpuidle_device *device; 63 struct resource *res;
64
65 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
66 if (res == NULL)
67 return -EINVAL;
68
69 ddr_operation_base = devm_request_and_ioremap(&pdev->dev, res);
70 if (!ddr_operation_base)
71 return -EADDRNOTAVAIL;
61 72
62 device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); 73 device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
63 device->state_count = KIRKWOOD_MAX_STATES; 74 device->state_count = KIRKWOOD_MAX_STATES;
@@ -70,4 +81,26 @@ static int kirkwood_init_cpuidle(void)
70 return 0; 81 return 0;
71} 82}
72 83
73device_initcall(kirkwood_init_cpuidle); 84int kirkwood_cpuidle_remove(struct platform_device *pdev)
85{
86 cpuidle_unregister_device(device);
87 cpuidle_unregister_driver(&kirkwood_idle_driver);
88
89 return 0;
90}
91
92static struct platform_driver kirkwood_cpuidle_driver = {
93 .probe = kirkwood_cpuidle_probe,
94 .remove = kirkwood_cpuidle_remove,
95 .driver = {
96 .name = "kirkwood_cpuidle",
97 .owner = THIS_MODULE,
98 },
99};
100
101module_platform_driver(kirkwood_cpuidle_driver);
102
103MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
104MODULE_DESCRIPTION("Kirkwood cpu idle driver");
105MODULE_LICENSE("GPL v2");
106MODULE_ALIAS("platform:kirkwood-cpuidle");
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 58c1896271e1..f6c018f1b453 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -32,8 +32,8 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/clk/tegra.h>
35 36
36#include <mach/clk.h>
37#include "dmaengine.h" 37#include "dmaengine.h"
38 38
39#define TEGRA_APBDMA_GENERAL 0x0 39#define TEGRA_APBDMA_GENERAL 0x0
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index d365c6dff0fb..b6679b36700f 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -12,8 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of.h> 13#include <linux/of.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15 15#include <linux/clk/tegra.h>
16#include <mach/clk.h>
17 16
18#include "drm.h" 17#include "drm.h"
19#include "dc.h" 18#include "dc.h"
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 3a503c9e4686..d980dc75788c 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -11,7 +11,6 @@
11#include <linux/of_address.h> 11#include <linux/of_address.h>
12#include <linux/of_platform.h> 12#include <linux/of_platform.h>
13 13
14#include <mach/clk.h>
15#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
16#include <asm/dma-iommu.h> 15#include <asm/dma-iommu.h>
17 16
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 266af7879240..d4f3fb9f0c29 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -14,8 +14,7 @@
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/regulator/consumer.h> 16#include <linux/regulator/consumer.h>
17 17#include <linux/clk/tegra.h>
18#include <mach/clk.h>
19 18
20#include "hdmi.h" 19#include "hdmi.h"
21#include "drm.h" 20#include "drm.h"
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 1fb30099dac4..f0d9923323ea 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -29,11 +29,10 @@
29#include <linux/of_i2c.h> 29#include <linux/of_i2c.h>
30#include <linux/of_device.h> 30#include <linux/of_device.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/clk/tegra.h>
32 33
33#include <asm/unaligned.h> 34#include <asm/unaligned.h>
34 35
35#include <mach/clk.h>
36
37#define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000)) 36#define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000))
38#define BYTES_PER_FIFO_WORD 4 37#define BYTES_PER_FIFO_WORD 4
39 38
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index d89e7d392d1e..0e138ebcc768 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -30,7 +30,7 @@
30#include <linux/clk.h> 30#include <linux/clk.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/input/matrix_keypad.h> 32#include <linux/input/matrix_keypad.h>
33#include <mach/clk.h> 33#include <linux/clk/tegra.h>
34 34
35#define KBC_MAX_GPIO 24 35#define KBC_MAX_GPIO 24
36#define KBC_MAX_KPENT 8 36#define KBC_MAX_KPENT 8
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index aa64d5d3fb20..476d06452af8 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1033,7 +1033,7 @@ config RTC_DRV_TX4939
1033 1033
1034config RTC_DRV_MV 1034config RTC_DRV_MV
1035 tristate "Marvell SoC RTC" 1035 tristate "Marvell SoC RTC"
1036 depends on ARCH_KIRKWOOD || ARCH_DOVE 1036 depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU
1037 help 1037 help
1038 If you say yes here you will get support for the in-chip RTC 1038 If you say yes here you will get support for the in-chip RTC
1039 that can be found in some of Marvell's SoC devices, such as 1039 that can be found in some of Marvell's SoC devices, such as
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c
index 8a61b27a9f2d..3d6a12b2af04 100644
--- a/drivers/spi/spi-tegra20-sflash.c
+++ b/drivers/spi/spi-tegra20-sflash.c
@@ -34,7 +34,7 @@
34#include <linux/of_device.h> 34#include <linux/of_device.h>
35#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
36#include <linux/spi/spi-tegra.h> 36#include <linux/spi/spi-tegra.h>
37#include <mach/clk.h> 37#include <linux/clk/tegra.h>
38 38
39#define SPI_COMMAND 0x000 39#define SPI_COMMAND 0x000
40#define SPI_GO BIT(30) 40#define SPI_GO BIT(30)
@@ -531,7 +531,7 @@ static int tegra_sflash_probe(struct platform_device *pdev)
531 goto exit_free_master; 531 goto exit_free_master;
532 } 532 }
533 533
534 tsd->clk = devm_clk_get(&pdev->dev, "spi"); 534 tsd->clk = devm_clk_get(&pdev->dev, NULL);
535 if (IS_ERR(tsd->clk)) { 535 if (IS_ERR(tsd->clk)) {
536 dev_err(&pdev->dev, "can not get clock\n"); 536 dev_err(&pdev->dev, "can not get clock\n");
537 ret = PTR_ERR(tsd->clk); 537 ret = PTR_ERR(tsd->clk);
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
index 8458c4bf7172..b8698b389ef3 100644
--- a/drivers/spi/spi-tegra20-slink.c
+++ b/drivers/spi/spi-tegra20-slink.c
@@ -35,7 +35,7 @@
35#include <linux/of_device.h> 35#include <linux/of_device.h>
36#include <linux/spi/spi.h> 36#include <linux/spi/spi.h>
37#include <linux/spi/spi-tegra.h> 37#include <linux/spi/spi-tegra.h>
38#include <mach/clk.h> 38#include <linux/clk/tegra.h>
39 39
40#define SLINK_COMMAND 0x000 40#define SLINK_COMMAND 0x000
41#define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) 41#define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0)
@@ -1186,7 +1186,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
1186 goto exit_free_master; 1186 goto exit_free_master;
1187 } 1187 }
1188 1188
1189 tspi->clk = devm_clk_get(&pdev->dev, "slink"); 1189 tspi->clk = devm_clk_get(&pdev->dev, NULL);
1190 if (IS_ERR(tspi->clk)) { 1190 if (IS_ERR(tspi->clk)) {
1191 dev_err(&pdev->dev, "can not get clock\n"); 1191 dev_err(&pdev->dev, "can not get clock\n");
1192 ret = PTR_ERR(tspi->clk); 1192 ret = PTR_ERR(tspi->clk);
diff --git a/drivers/staging/nvec/TODO b/drivers/staging/nvec/TODO
index f950ab890e2e..e5ae42a0b44a 100644
--- a/drivers/staging/nvec/TODO
+++ b/drivers/staging/nvec/TODO
@@ -1,9 +1,5 @@
1ToDo list (incomplete, unordered) 1ToDo list (incomplete, unordered)
2 - add compile as module support 2 - add compile as module support
3 - fix clk usage
4 should not be using clk_get_sys(), but clk_get(&pdev->dev, conn)
5 where conn is either NULL if the device only has one clock, or
6 the device specific name if it has multiple clocks.
7 - move half of the nvec init stuff to i2c-tegra.c 3 - move half of the nvec init stuff to i2c-tegra.c
8 - move event handling to nvec_events 4 - move event handling to nvec_events
9 - finish suspend/resume support 5 - finish suspend/resume support
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index 6a0b6eccf1e6..cf159365b0ee 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -37,8 +37,7 @@
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <linux/workqueue.h> 39#include <linux/workqueue.h>
40 40#include <linux/clk/tegra.h>
41#include <mach/clk.h>
42 41
43#include "nvec.h" 42#include "nvec.h"
44 43
@@ -816,7 +815,7 @@ static int tegra_nvec_probe(struct platform_device *pdev)
816 return -ENODEV; 815 return -ENODEV;
817 } 816 }
818 817
819 i2c_clk = clk_get_sys("tegra-i2c.2", "div-clk"); 818 i2c_clk = clk_get(&pdev->dev, "div-clk");
820 if (IS_ERR(i2c_clk)) { 819 if (IS_ERR(i2c_clk)) {
821 dev_err(nvec->dev, "failed to get controller clock\n"); 820 dev_err(nvec->dev, "failed to get controller clock\n");
822 return -ENODEV; 821 return -ENODEV;
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index acf17556bd87..568aecc7075b 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -2,7 +2,7 @@
2 * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs 2 * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2009 NVIDIA Corporation 5 * Copyright (C) 2009 - 2013 NVIDIA Corporation
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -26,23 +26,28 @@
26#include <linux/of.h> 26#include <linux/of.h>
27#include <linux/of_gpio.h> 27#include <linux/of_gpio.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29 29#include <linux/usb/ehci_def.h>
30#include <linux/usb/tegra_usb_phy.h> 30#include <linux/usb/tegra_usb_phy.h>
31 31
32#define TEGRA_USB_BASE 0xC5000000 32#define TEGRA_USB_BASE 0xC5000000
33#define TEGRA_USB2_BASE 0xC5004000 33#define TEGRA_USB2_BASE 0xC5004000
34#define TEGRA_USB3_BASE 0xC5008000 34#define TEGRA_USB3_BASE 0xC5008000
35 35
36/* PORTSC registers */
37#define TEGRA_USB_PORTSC1 0x184
38#define TEGRA_USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
39#define TEGRA_USB_PORTSC1_PHCD (1 << 23)
40
36#define TEGRA_USB_DMA_ALIGN 32 41#define TEGRA_USB_DMA_ALIGN 32
37 42
38struct tegra_ehci_hcd { 43struct tegra_ehci_hcd {
39 struct ehci_hcd *ehci; 44 struct ehci_hcd *ehci;
40 struct tegra_usb_phy *phy; 45 struct tegra_usb_phy *phy;
41 struct clk *clk; 46 struct clk *clk;
42 struct clk *emc_clk;
43 struct usb_phy *transceiver; 47 struct usb_phy *transceiver;
44 int host_resumed; 48 int host_resumed;
45 int port_resuming; 49 int port_resuming;
50 bool needs_double_reset;
46 enum tegra_usb_phy_port_speed port_speed; 51 enum tegra_usb_phy_port_speed port_speed;
47}; 52};
48 53
@@ -50,9 +55,8 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd)
50{ 55{
51 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); 56 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
52 57
53 clk_prepare_enable(tegra->emc_clk);
54 clk_prepare_enable(tegra->clk); 58 clk_prepare_enable(tegra->clk);
55 usb_phy_set_suspend(&tegra->phy->u_phy, 0); 59 usb_phy_set_suspend(hcd->phy, 0);
56 tegra->host_resumed = 1; 60 tegra->host_resumed = 1;
57} 61}
58 62
@@ -61,9 +65,8 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd)
61 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); 65 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
62 66
63 tegra->host_resumed = 0; 67 tegra->host_resumed = 0;
64 usb_phy_set_suspend(&tegra->phy->u_phy, 1); 68 usb_phy_set_suspend(hcd->phy, 1);
65 clk_disable_unprepare(tegra->clk); 69 clk_disable_unprepare(tegra->clk);
66 clk_disable_unprepare(tegra->emc_clk);
67} 70}
68 71
69static int tegra_ehci_internal_port_reset( 72static int tegra_ehci_internal_port_reset(
@@ -156,7 +159,7 @@ static int tegra_ehci_hub_control(
156 if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { 159 if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
157 /* Resume completed, re-enable disconnect detection */ 160 /* Resume completed, re-enable disconnect detection */
158 tegra->port_resuming = 0; 161 tegra->port_resuming = 0;
159 tegra_usb_phy_postresume(tegra->phy); 162 tegra_usb_phy_postresume(hcd->phy);
160 } 163 }
161 } 164 }
162 165
@@ -184,7 +187,7 @@ static int tegra_ehci_hub_control(
184 } 187 }
185 188
186 /* For USB1 port we need to issue Port Reset twice internally */ 189 /* For USB1 port we need to issue Port Reset twice internally */
187 if (tegra->phy->instance == 0 && 190 if (tegra->needs_double_reset &&
188 (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) { 191 (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) {
189 spin_unlock_irqrestore(&ehci->lock, flags); 192 spin_unlock_irqrestore(&ehci->lock, flags);
190 return tegra_ehci_internal_port_reset(ehci, status_reg); 193 return tegra_ehci_internal_port_reset(ehci, status_reg);
@@ -209,7 +212,7 @@ static int tegra_ehci_hub_control(
209 goto done; 212 goto done;
210 213
211 /* Disable disconnect detection during port resume */ 214 /* Disable disconnect detection during port resume */
212 tegra_usb_phy_preresume(tegra->phy); 215 tegra_usb_phy_preresume(hcd->phy);
213 216
214 ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); 217 ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25);
215 218
@@ -473,7 +476,7 @@ static int controller_resume(struct device *dev)
473 } 476 }
474 477
475 /* Force the phy to keep data lines in suspend state */ 478 /* Force the phy to keep data lines in suspend state */
476 tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); 479 tegra_ehci_phy_restore_start(hcd->phy, tegra->port_speed);
477 480
478 /* Enable host mode */ 481 /* Enable host mode */
479 tdi_reset(ehci); 482 tdi_reset(ehci);
@@ -540,17 +543,17 @@ static int controller_resume(struct device *dev)
540 } 543 }
541 } 544 }
542 545
543 tegra_ehci_phy_restore_end(tegra->phy); 546 tegra_ehci_phy_restore_end(hcd->phy);
544 goto done; 547 goto done;
545 548
546 restart: 549 restart:
547 if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) 550 if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH)
548 tegra_ehci_phy_restore_end(tegra->phy); 551 tegra_ehci_phy_restore_end(hcd->phy);
549 552
550 tegra_ehci_restart(hcd); 553 tegra_ehci_restart(hcd);
551 554
552 done: 555 done:
553 tegra_usb_phy_preresume(tegra->phy); 556 tegra_usb_phy_preresume(hcd->phy);
554 tegra->port_resuming = 1; 557 tegra->port_resuming = 1;
555 return 0; 558 return 0;
556} 559}
@@ -604,6 +607,37 @@ static const struct dev_pm_ops tegra_ehci_pm_ops = {
604 607
605#endif 608#endif
606 609
610/* Bits of PORTSC1, which will get cleared by writing 1 into them */
611#define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
612
613void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val)
614{
615 unsigned long val;
616 struct usb_hcd *hcd = bus_to_hcd(x->otg->host);
617 void __iomem *base = hcd->regs;
618
619 val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS;
620 val &= ~TEGRA_USB_PORTSC1_PTS(3);
621 val |= TEGRA_USB_PORTSC1_PTS(pts_val & 3);
622 writel(val, base + TEGRA_USB_PORTSC1);
623}
624EXPORT_SYMBOL_GPL(tegra_ehci_set_pts);
625
626void tegra_ehci_set_phcd(struct usb_phy *x, bool enable)
627{
628 unsigned long val;
629 struct usb_hcd *hcd = bus_to_hcd(x->otg->host);
630 void __iomem *base = hcd->regs;
631
632 val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS;
633 if (enable)
634 val |= TEGRA_USB_PORTSC1_PHCD;
635 else
636 val &= ~TEGRA_USB_PORTSC1_PHCD;
637 writel(val, base + TEGRA_USB_PORTSC1);
638}
639EXPORT_SYMBOL_GPL(tegra_ehci_set_phcd);
640
607static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); 641static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
608 642
609static int tegra_ehci_probe(struct platform_device *pdev) 643static int tegra_ehci_probe(struct platform_device *pdev)
@@ -615,6 +649,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
615 int err = 0; 649 int err = 0;
616 int irq; 650 int irq;
617 int instance = pdev->id; 651 int instance = pdev->id;
652 struct usb_phy *u_phy;
618 653
619 pdata = pdev->dev.platform_data; 654 pdata = pdev->dev.platform_data;
620 if (!pdata) { 655 if (!pdata) {
@@ -656,15 +691,8 @@ static int tegra_ehci_probe(struct platform_device *pdev)
656 if (err) 691 if (err)
657 goto fail_clk; 692 goto fail_clk;
658 693
659 tegra->emc_clk = devm_clk_get(&pdev->dev, "emc"); 694 tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node,
660 if (IS_ERR(tegra->emc_clk)) { 695 "nvidia,needs-double-reset");
661 dev_err(&pdev->dev, "Can't get emc clock\n");
662 err = PTR_ERR(tegra->emc_clk);
663 goto fail_emc_clk;
664 }
665
666 clk_prepare_enable(tegra->emc_clk);
667 clk_set_rate(tegra->emc_clk, 400000000);
668 696
669 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 697 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
670 if (!res) { 698 if (!res) {
@@ -712,9 +740,19 @@ static int tegra_ehci_probe(struct platform_device *pdev)
712 goto fail_io; 740 goto fail_io;
713 } 741 }
714 742
715 usb_phy_init(&tegra->phy->u_phy); 743 hcd->phy = u_phy = &tegra->phy->u_phy;
744 usb_phy_init(hcd->phy);
745
746 u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg),
747 GFP_KERNEL);
748 if (!u_phy->otg) {
749 dev_err(&pdev->dev, "Failed to alloc memory for otg\n");
750 err = -ENOMEM;
751 goto fail_io;
752 }
753 u_phy->otg->host = hcd_to_bus(hcd);
716 754
717 err = usb_phy_set_suspend(&tegra->phy->u_phy, 0); 755 err = usb_phy_set_suspend(hcd->phy, 0);
718 if (err) { 756 if (err) {
719 dev_err(&pdev->dev, "Failed to power on the phy\n"); 757 dev_err(&pdev->dev, "Failed to power on the phy\n");
720 goto fail; 758 goto fail;
@@ -760,10 +798,8 @@ fail:
760 if (!IS_ERR_OR_NULL(tegra->transceiver)) 798 if (!IS_ERR_OR_NULL(tegra->transceiver))
761 otg_set_host(tegra->transceiver->otg, NULL); 799 otg_set_host(tegra->transceiver->otg, NULL);
762#endif 800#endif
763 usb_phy_shutdown(&tegra->phy->u_phy); 801 usb_phy_shutdown(hcd->phy);
764fail_io: 802fail_io:
765 clk_disable_unprepare(tegra->emc_clk);
766fail_emc_clk:
767 clk_disable_unprepare(tegra->clk); 803 clk_disable_unprepare(tegra->clk);
768fail_clk: 804fail_clk:
769 usb_put_hcd(hcd); 805 usb_put_hcd(hcd);
@@ -784,15 +820,12 @@ static int tegra_ehci_remove(struct platform_device *pdev)
784 otg_set_host(tegra->transceiver->otg, NULL); 820 otg_set_host(tegra->transceiver->otg, NULL);
785#endif 821#endif
786 822
823 usb_phy_shutdown(hcd->phy);
787 usb_remove_hcd(hcd); 824 usb_remove_hcd(hcd);
788 usb_put_hcd(hcd); 825 usb_put_hcd(hcd);
789 826
790 usb_phy_shutdown(&tegra->phy->u_phy);
791
792 clk_disable_unprepare(tegra->clk); 827 clk_disable_unprepare(tegra->clk);
793 828
794 clk_disable_unprepare(tegra->emc_clk);
795
796 return 0; 829 return 0;
797} 830}
798 831
diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c
index 9d13c81754e0..5487d38481af 100644
--- a/drivers/usb/phy/tegra_usb_phy.c
+++ b/drivers/usb/phy/tegra_usb_phy.c
@@ -24,6 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/gpio.h> 26#include <linux/gpio.h>
27#include <linux/of.h>
27#include <linux/of_gpio.h> 28#include <linux/of_gpio.h>
28#include <linux/usb/otg.h> 29#include <linux/usb/otg.h>
29#include <linux/usb/ulpi.h> 30#include <linux/usb/ulpi.h>
@@ -35,19 +36,6 @@
35 36
36#define ULPI_VIEWPORT 0x170 37#define ULPI_VIEWPORT 0x170
37 38
38#define USB_PORTSC1 0x184
39#define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
40#define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26)
41#define USB_PORTSC1_PHCD (1 << 23)
42#define USB_PORTSC1_WKOC (1 << 22)
43#define USB_PORTSC1_WKDS (1 << 21)
44#define USB_PORTSC1_WKCN (1 << 20)
45#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16)
46#define USB_PORTSC1_PP (1 << 12)
47#define USB_PORTSC1_SUSP (1 << 7)
48#define USB_PORTSC1_PE (1 << 2)
49#define USB_PORTSC1_CCS (1 << 0)
50
51#define USB_SUSP_CTRL 0x400 39#define USB_SUSP_CTRL 0x400
52#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) 40#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
53#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) 41#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
@@ -208,11 +196,6 @@ static struct tegra_utmip_config utmip_default[] = {
208 }, 196 },
209}; 197};
210 198
211static inline bool phy_is_ulpi(struct tegra_usb_phy *phy)
212{
213 return (phy->instance == 1);
214}
215
216static int utmip_pad_open(struct tegra_usb_phy *phy) 199static int utmip_pad_open(struct tegra_usb_phy *phy)
217{ 200{
218 phy->pad_clk = clk_get_sys("utmip-pad", NULL); 201 phy->pad_clk = clk_get_sys("utmip-pad", NULL);
@@ -221,7 +204,7 @@ static int utmip_pad_open(struct tegra_usb_phy *phy)
221 return PTR_ERR(phy->pad_clk); 204 return PTR_ERR(phy->pad_clk);
222 } 205 }
223 206
224 if (phy->instance == 0) { 207 if (phy->is_legacy_phy) {
225 phy->pad_regs = phy->regs; 208 phy->pad_regs = phy->regs;
226 } else { 209 } else {
227 phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE); 210 phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE);
@@ -236,7 +219,7 @@ static int utmip_pad_open(struct tegra_usb_phy *phy)
236 219
237static void utmip_pad_close(struct tegra_usb_phy *phy) 220static void utmip_pad_close(struct tegra_usb_phy *phy)
238{ 221{
239 if (phy->instance != 0) 222 if (!phy->is_legacy_phy)
240 iounmap(phy->pad_regs); 223 iounmap(phy->pad_regs);
241 clk_put(phy->pad_clk); 224 clk_put(phy->pad_clk);
242} 225}
@@ -305,7 +288,7 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
305 unsigned long val; 288 unsigned long val;
306 void __iomem *base = phy->regs; 289 void __iomem *base = phy->regs;
307 290
308 if (phy->instance == 0) { 291 if (phy->is_legacy_phy) {
309 val = readl(base + USB_SUSP_CTRL); 292 val = readl(base + USB_SUSP_CTRL);
310 val |= USB_SUSP_SET; 293 val |= USB_SUSP_SET;
311 writel(val, base + USB_SUSP_CTRL); 294 writel(val, base + USB_SUSP_CTRL);
@@ -315,13 +298,8 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
315 val = readl(base + USB_SUSP_CTRL); 298 val = readl(base + USB_SUSP_CTRL);
316 val &= ~USB_SUSP_SET; 299 val &= ~USB_SUSP_SET;
317 writel(val, base + USB_SUSP_CTRL); 300 writel(val, base + USB_SUSP_CTRL);
318 } 301 } else
319 302 tegra_ehci_set_phcd(&phy->u_phy, true);
320 if (phy->instance == 2) {
321 val = readl(base + USB_PORTSC1);
322 val |= USB_PORTSC1_PHCD;
323 writel(val, base + USB_PORTSC1);
324 }
325 303
326 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) 304 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
327 pr_err("%s: timeout waiting for phy to stabilize\n", __func__); 305 pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
@@ -332,7 +310,7 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
332 unsigned long val; 310 unsigned long val;
333 void __iomem *base = phy->regs; 311 void __iomem *base = phy->regs;
334 312
335 if (phy->instance == 0) { 313 if (phy->is_legacy_phy) {
336 val = readl(base + USB_SUSP_CTRL); 314 val = readl(base + USB_SUSP_CTRL);
337 val |= USB_SUSP_CLR; 315 val |= USB_SUSP_CLR;
338 writel(val, base + USB_SUSP_CTRL); 316 writel(val, base + USB_SUSP_CTRL);
@@ -342,13 +320,8 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
342 val = readl(base + USB_SUSP_CTRL); 320 val = readl(base + USB_SUSP_CTRL);
343 val &= ~USB_SUSP_CLR; 321 val &= ~USB_SUSP_CLR;
344 writel(val, base + USB_SUSP_CTRL); 322 writel(val, base + USB_SUSP_CTRL);
345 } 323 } else
346 324 tegra_ehci_set_phcd(&phy->u_phy, false);
347 if (phy->instance == 2) {
348 val = readl(base + USB_PORTSC1);
349 val &= ~USB_PORTSC1_PHCD;
350 writel(val, base + USB_PORTSC1);
351 }
352 325
353 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 326 if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
354 USB_PHY_CLK_VALID)) 327 USB_PHY_CLK_VALID))
@@ -365,7 +338,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
365 val |= UTMIP_RESET; 338 val |= UTMIP_RESET;
366 writel(val, base + USB_SUSP_CTRL); 339 writel(val, base + USB_SUSP_CTRL);
367 340
368 if (phy->instance == 0) { 341 if (phy->is_legacy_phy) {
369 val = readl(base + USB1_LEGACY_CTRL); 342 val = readl(base + USB1_LEGACY_CTRL);
370 val |= USB1_NO_LEGACY_MODE; 343 val |= USB1_NO_LEGACY_MODE;
371 writel(val, base + USB1_LEGACY_CTRL); 344 writel(val, base + USB1_LEGACY_CTRL);
@@ -440,16 +413,14 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
440 val |= UTMIP_BIAS_PDTRK_COUNT(0x5); 413 val |= UTMIP_BIAS_PDTRK_COUNT(0x5);
441 writel(val, base + UTMIP_BIAS_CFG1); 414 writel(val, base + UTMIP_BIAS_CFG1);
442 415
443 if (phy->instance == 0) { 416 if (phy->is_legacy_phy) {
444 val = readl(base + UTMIP_SPARE_CFG0); 417 val = readl(base + UTMIP_SPARE_CFG0);
445 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) 418 if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)
446 val &= ~FUSE_SETUP_SEL; 419 val &= ~FUSE_SETUP_SEL;
447 else 420 else
448 val |= FUSE_SETUP_SEL; 421 val |= FUSE_SETUP_SEL;
449 writel(val, base + UTMIP_SPARE_CFG0); 422 writel(val, base + UTMIP_SPARE_CFG0);
450 } 423 } else {
451
452 if (phy->instance == 2) {
453 val = readl(base + USB_SUSP_CTRL); 424 val = readl(base + USB_SUSP_CTRL);
454 val |= UTMIP_PHY_ENABLE; 425 val |= UTMIP_PHY_ENABLE;
455 writel(val, base + USB_SUSP_CTRL); 426 writel(val, base + USB_SUSP_CTRL);
@@ -459,7 +430,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
459 val &= ~UTMIP_RESET; 430 val &= ~UTMIP_RESET;
460 writel(val, base + USB_SUSP_CTRL); 431 writel(val, base + USB_SUSP_CTRL);
461 432
462 if (phy->instance == 0) { 433 if (phy->is_legacy_phy) {
463 val = readl(base + USB1_LEGACY_CTRL); 434 val = readl(base + USB1_LEGACY_CTRL);
464 val &= ~USB1_VBUS_SENSE_CTL_MASK; 435 val &= ~USB1_VBUS_SENSE_CTL_MASK;
465 val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD; 436 val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD;
@@ -472,11 +443,8 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
472 443
473 utmi_phy_clk_enable(phy); 444 utmi_phy_clk_enable(phy);
474 445
475 if (phy->instance == 2) { 446 if (!phy->is_legacy_phy)
476 val = readl(base + USB_PORTSC1); 447 tegra_ehci_set_pts(&phy->u_phy, 0);
477 val &= ~USB_PORTSC1_PTS(~0);
478 writel(val, base + USB_PORTSC1);
479 }
480 448
481 return 0; 449 return 0;
482} 450}
@@ -621,10 +589,6 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
621 return ret; 589 return ret;
622 } 590 }
623 591
624 val = readl(base + USB_PORTSC1);
625 val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN;
626 writel(val, base + USB_PORTSC1);
627
628 val = readl(base + USB_SUSP_CTRL); 592 val = readl(base + USB_SUSP_CTRL);
629 val |= USB_SUSP_CLR; 593 val |= USB_SUSP_CLR;
630 writel(val, base + USB_SUSP_CTRL); 594 writel(val, base + USB_SUSP_CTRL);
@@ -639,17 +603,8 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
639 603
640static int ulpi_phy_power_off(struct tegra_usb_phy *phy) 604static int ulpi_phy_power_off(struct tegra_usb_phy *phy)
641{ 605{
642 unsigned long val;
643 void __iomem *base = phy->regs;
644 struct tegra_ulpi_config *config = phy->config; 606 struct tegra_ulpi_config *config = phy->config;
645 607
646 /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB
647 * Controller to immediately bring the ULPI PHY out of low power
648 */
649 val = readl(base + USB_PORTSC1);
650 val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
651 writel(val, base + USB_PORTSC1);
652
653 clk_disable(phy->clk); 608 clk_disable(phy->clk);
654 return gpio_direction_output(config->reset_gpio, 0); 609 return gpio_direction_output(config->reset_gpio, 0);
655} 610}
@@ -660,7 +615,7 @@ static int tegra_phy_init(struct usb_phy *x)
660 struct tegra_ulpi_config *ulpi_config; 615 struct tegra_ulpi_config *ulpi_config;
661 int err; 616 int err;
662 617
663 if (phy_is_ulpi(phy)) { 618 if (phy->is_ulpi_phy) {
664 ulpi_config = phy->config; 619 ulpi_config = phy->config;
665 phy->clk = clk_get_sys(NULL, ulpi_config->clk); 620 phy->clk = clk_get_sys(NULL, ulpi_config->clk);
666 if (IS_ERR(phy->clk)) { 621 if (IS_ERR(phy->clk)) {
@@ -698,7 +653,7 @@ static void tegra_usb_phy_close(struct usb_phy *x)
698{ 653{
699 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); 654 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
700 655
701 if (phy_is_ulpi(phy)) 656 if (phy->is_ulpi_phy)
702 clk_put(phy->clk); 657 clk_put(phy->clk);
703 else 658 else
704 utmip_pad_close(phy); 659 utmip_pad_close(phy);
@@ -709,7 +664,7 @@ static void tegra_usb_phy_close(struct usb_phy *x)
709 664
710static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) 665static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
711{ 666{
712 if (phy_is_ulpi(phy)) 667 if (phy->is_ulpi_phy)
713 return ulpi_phy_power_on(phy); 668 return ulpi_phy_power_on(phy);
714 else 669 else
715 return utmi_phy_power_on(phy); 670 return utmi_phy_power_on(phy);
@@ -717,7 +672,7 @@ static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
717 672
718static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) 673static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
719{ 674{
720 if (phy_is_ulpi(phy)) 675 if (phy->is_ulpi_phy)
721 return ulpi_phy_power_off(phy); 676 return ulpi_phy_power_off(phy);
722 else 677 else
723 return utmi_phy_power_off(phy); 678 return utmi_phy_power_off(phy);
@@ -739,8 +694,9 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
739 unsigned long parent_rate; 694 unsigned long parent_rate;
740 int i; 695 int i;
741 int err; 696 int err;
697 struct device_node *np = dev->of_node;
742 698
743 phy = kmalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); 699 phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL);
744 if (!phy) 700 if (!phy)
745 return ERR_PTR(-ENOMEM); 701 return ERR_PTR(-ENOMEM);
746 702
@@ -749,9 +705,16 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
749 phy->config = config; 705 phy->config = config;
750 phy->mode = phy_mode; 706 phy->mode = phy_mode;
751 phy->dev = dev; 707 phy->dev = dev;
708 phy->is_legacy_phy =
709 of_property_read_bool(np, "nvidia,has-legacy-mode");
710 err = of_property_match_string(np, "phy_type", "ulpi");
711 if (err < 0)
712 phy->is_ulpi_phy = false;
713 else
714 phy->is_ulpi_phy = true;
752 715
753 if (!phy->config) { 716 if (!phy->config) {
754 if (phy_is_ulpi(phy)) { 717 if (phy->is_ulpi_phy) {
755 pr_err("%s: ulpi phy configuration missing", __func__); 718 pr_err("%s: ulpi phy configuration missing", __func__);
756 err = -EINVAL; 719 err = -EINVAL;
757 goto err0; 720 goto err0;
@@ -796,45 +759,40 @@ err0:
796} 759}
797EXPORT_SYMBOL_GPL(tegra_usb_phy_open); 760EXPORT_SYMBOL_GPL(tegra_usb_phy_open);
798 761
799void tegra_usb_phy_preresume(struct tegra_usb_phy *phy) 762void tegra_usb_phy_preresume(struct usb_phy *x)
800{ 763{
801 if (!phy_is_ulpi(phy)) 764 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
765
766 if (!phy->is_ulpi_phy)
802 utmi_phy_preresume(phy); 767 utmi_phy_preresume(phy);
803} 768}
804EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume); 769EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume);
805 770
806void tegra_usb_phy_postresume(struct tegra_usb_phy *phy) 771void tegra_usb_phy_postresume(struct usb_phy *x)
807{ 772{
808 if (!phy_is_ulpi(phy)) 773 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
774
775 if (!phy->is_ulpi_phy)
809 utmi_phy_postresume(phy); 776 utmi_phy_postresume(phy);
810} 777}
811EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume); 778EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume);
812 779
813void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, 780void tegra_ehci_phy_restore_start(struct usb_phy *x,
814 enum tegra_usb_phy_port_speed port_speed) 781 enum tegra_usb_phy_port_speed port_speed)
815{ 782{
816 if (!phy_is_ulpi(phy)) 783 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
784
785 if (!phy->is_ulpi_phy)
817 utmi_phy_restore_start(phy, port_speed); 786 utmi_phy_restore_start(phy, port_speed);
818} 787}
819EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start); 788EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start);
820 789
821void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy) 790void tegra_ehci_phy_restore_end(struct usb_phy *x)
822{ 791{
823 if (!phy_is_ulpi(phy)) 792 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
793
794 if (!phy->is_ulpi_phy)
824 utmi_phy_restore_end(phy); 795 utmi_phy_restore_end(phy);
825} 796}
826EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end); 797EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end);
827 798
828void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy)
829{
830 if (!phy_is_ulpi(phy))
831 utmi_phy_clk_disable(phy);
832}
833EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_disable);
834
835void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy)
836{
837 if (!phy_is_ulpi(phy))
838 utmi_phy_clk_enable(phy);
839}
840EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable);
diff --git a/arch/arm/mach-tegra/tegra_cpu_car.h b/include/linux/clk/tegra.h
index 9764d31032b7..404d6f940872 100644
--- a/arch/arm/mach-tegra/tegra_cpu_car.h
+++ b/include/linux/clk/tegra.h
@@ -14,8 +14,10 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef __MACH_TEGRA_CPU_CAR_H 17#ifndef __LINUX_CLK_TEGRA_H_
18#define __MACH_TEGRA_CPU_CAR_H 18#define __LINUX_CLK_TEGRA_H_
19
20#include <linux/clk.h>
19 21
20/* 22/*
21 * Tegra CPU clock and reset control ops 23 * Tegra CPU clock and reset control ops
@@ -118,7 +120,8 @@ static inline void tegra_cpu_clock_resume(void)
118} 120}
119#endif 121#endif
120 122
121void tegra20_cpu_car_ops_init(void); 123void tegra_periph_reset_deassert(struct clk *c);
122void tegra30_cpu_car_ops_init(void); 124void tegra_periph_reset_assert(struct clk *c);
125void tegra_clocks_init(void);
123 126
124#endif /* __MACH_TEGRA_CPU_CAR_H */ 127#endif /* __LINUX_CLK_TEGRA_H_ */
diff --git a/include/linux/platform_data/usb-omap.h b/include/linux/platform_data/usb-omap.h
index ef65b67c56c3..e697c85ad3bc 100644
--- a/include/linux/platform_data/usb-omap.h
+++ b/include/linux/platform_data/usb-omap.h
@@ -55,13 +55,17 @@ struct ohci_hcd_omap_platform_data {
55}; 55};
56 56
57struct usbhs_omap_platform_data { 57struct usbhs_omap_platform_data {
58 enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; 58 enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
59 int reset_gpio_port[OMAP3_HS_USB_PORTS];
60 struct regulator *regulator[OMAP3_HS_USB_PORTS];
59 61
60 struct ehci_hcd_omap_platform_data *ehci_data; 62 struct ehci_hcd_omap_platform_data *ehci_data;
61 struct ohci_hcd_omap_platform_data *ohci_data; 63 struct ohci_hcd_omap_platform_data *ohci_data;
62 64
63 /* OMAP3 <= ES2.1 have a single ulpi bypass control bit */ 65 /* OMAP3 <= ES2.1 have a single ulpi bypass control bit */
64 unsigned single_ulpi_bypass:1; 66 unsigned single_ulpi_bypass:1;
67 unsigned es2_compatibility:1;
68 unsigned phy_reset:1;
65}; 69};
66 70
67/*-------------------------------------------------------------------------*/ 71/*-------------------------------------------------------------------------*/
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
new file mode 100644
index 000000000000..95f611d78f3a
--- /dev/null
+++ b/include/linux/tegra-soc.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __LINUX_TEGRA_SOC_H_
18#define __LINUX_TEGRA_SOC_H_
19
20u32 tegra_read_chipid(void);
21
22#endif /* __LINUX_TEGRA_SOC_H_ */
diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h
index 176b1ca06ae4..9ebebe906925 100644
--- a/include/linux/usb/tegra_usb_phy.h
+++ b/include/linux/usb/tegra_usb_phy.h
@@ -59,22 +59,24 @@ struct tegra_usb_phy {
59 struct usb_phy *ulpi; 59 struct usb_phy *ulpi;
60 struct usb_phy u_phy; 60 struct usb_phy u_phy;
61 struct device *dev; 61 struct device *dev;
62 bool is_legacy_phy;
63 bool is_ulpi_phy;
62}; 64};
63 65
64struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, 66struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
65 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode); 67 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode);
66 68
67void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy); 69void tegra_usb_phy_preresume(struct usb_phy *phy);
68 70
69void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy); 71void tegra_usb_phy_postresume(struct usb_phy *phy);
70 72
71void tegra_usb_phy_preresume(struct tegra_usb_phy *phy); 73void tegra_ehci_phy_restore_start(struct usb_phy *phy,
74 enum tegra_usb_phy_port_speed port_speed);
72 75
73void tegra_usb_phy_postresume(struct tegra_usb_phy *phy); 76void tegra_ehci_phy_restore_end(struct usb_phy *phy);
74 77
75void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, 78void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val);
76 enum tegra_usb_phy_port_speed port_speed);
77 79
78void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy); 80void tegra_ehci_set_phcd(struct usb_phy *x, bool enable);
79 81
80#endif /* __TEGRA_USB_PHY_H */ 82#endif /* __TEGRA_USB_PHY_H */
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index dd146f10fef2..e5cfb4ac41ba 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -25,7 +25,7 @@
25#include <linux/pm_runtime.h> 25#include <linux/pm_runtime.h>
26#include <linux/regmap.h> 26#include <linux/regmap.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <mach/clk.h> 28#include <linux/clk/tegra.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include "tegra30_ahub.h" 30#include "tegra30_ahub.h"
31 31
@@ -299,15 +299,6 @@ static const char * const configlink_clocks[] = {
299 "spdif_in", 299 "spdif_in",
300}; 300};
301 301
302struct of_dev_auxdata ahub_auxdata[] = {
303 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080300, "tegra30-i2s.0", NULL),
304 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080400, "tegra30-i2s.1", NULL),
305 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080500, "tegra30-i2s.2", NULL),
306 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080600, "tegra30-i2s.3", NULL),
307 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080700, "tegra30-i2s.4", NULL),
308 {}
309};
310
311#define LAST_REG(name) \ 302#define LAST_REG(name) \
312 (TEGRA30_AHUB_##name + \ 303 (TEGRA30_AHUB_##name + \
313 (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4) 304 (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4)
@@ -451,7 +442,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
451 * Ensure that here. 442 * Ensure that here.
452 */ 443 */
453 for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { 444 for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) {
454 clk = clk_get_sys(NULL, configlink_clocks[i]); 445 clk = clk_get(&pdev->dev, configlink_clocks[i]);
455 if (IS_ERR(clk)) { 446 if (IS_ERR(clk)) {
456 dev_err(&pdev->dev, "Can't get clock %s\n", 447 dev_err(&pdev->dev, "Can't get clock %s\n",
457 configlink_clocks[i]); 448 configlink_clocks[i]);
@@ -569,8 +560,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
569 goto err_pm_disable; 560 goto err_pm_disable;
570 } 561 }
571 562
572 of_platform_populate(pdev->dev.of_node, NULL, ahub_auxdata, 563 of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
573 &pdev->dev);
574 564
575 return 0; 565 return 0;
576 566