Pull ARM SoC platform support updates from Kevin Hilman: "Our SoC branch usually contains expanded support for new SoCs and other core platform code. Some highlights from this round: - sunxi: SMP support for A23 SoC - socpga: big-endian support - pxa: conversion to common clock framework - bcm: SMP support for BCM63138 - imx: support new I.MX7D SoC - zte: basic support for ZX296702 SoC" * tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (134 commits) ARM: zx: Add basic defconfig support for ZX296702 ARM: dts: zx: add an initial zx296702 dts and doc clk: zx: add clock support to zx296702 dt-bindings: Add #defines for ZTE ZX296702 clocks ARM: socfpga: fix build error due to secondary_startup MAINTAINERS: ARM64: EXYNOS: Extend entry for ARM64 DTS ARM: ep93xx: simone: support for SPI-based MMC/SD cards MAINTAINERS: update Shawn's email to use kernel.org one ARM: socfpga: support suspend to ram ARM: socfpga: add CPU_METHOD_OF_DECLARE for Arria 10 ARM: socfpga: use CPU_METHOD_OF_DECLARE for socfpga_cyclone5 ARM: EXYNOS: register power domain driver from core_initcall ARM: EXYNOS: use PS_HOLD based poweroff for all supported SoCs ARM: SAMSUNG: Constify platform_device_id ARM: EXYNOS: Constify irq_domain_ops ARM: EXYNOS: add coupled cpuidle support for Exynos3250 ARM: EXYNOS: add exynos_get_boot_addr() helper ARM: EXYNOS: add exynos_set_boot_addr() helper ARM: EXYNOS: make exynos_core_restart() less verbose ARM: EXYNOS: fix exynos_boot_secondary() return value on timeout ...
Unified · Split
| @@ -0,0 +1,32 @@ | ||
| 1 | + STM32 ARM Linux Overview | |
| 2 | + ======================== | |
| 3 | + | |
| 4 | +Introduction | |
| 5 | +------------ | |
| 6 | + | |
| 7 | + The STMicroelectronics family of Cortex-M based MCUs are supported by the | |
| 8 | + 'STM32' platform of ARM Linux. Currently only the STM32F429 is supported. | |
| 9 | + | |
| 10 | + | |
| 11 | +Configuration | |
| 12 | +------------- | |
| 13 | + | |
| 14 | + A generic configuration is provided for STM32 family, and can be used as the | |
| 15 | + default by | |
| 16 | + make stm32_defconfig | |
| 17 | + | |
| 18 | +Layout | |
| 19 | +------ | |
| 20 | + | |
| 21 | + All the files for multiple machine families are located in the platform code | |
| 22 | + contained in arch/arm/mach-stm32 | |
| 23 | + | |
| 24 | + There is a generic board board-dt.c in the mach folder which support | |
| 25 | + Flattened Device Tree, which means, it works with any compatible board with | |
| 26 | + Device Trees. | |
| 27 | + | |
| 28 | + | |
| 29 | +Document Author | |
| 30 | +--------------- | |
| 31 | + | |
| 32 | + Maxime Coquelin <mcoquelin.stm32@gmail.com> | |
| @@ -0,0 +1,22 @@ | ||
| 1 | + STM32F429 Overview | |
| 2 | + ================== | |
| 3 | + | |
| 4 | + Introduction | |
| 5 | + ------------ | |
| 6 | + The STM32F429 is a Cortex-M4 MCU aimed at various applications. | |
| 7 | + It features: | |
| 8 | + - ARM Cortex-M4 up to 180MHz with FPU | |
| 9 | + - 2MB internal Flash Memory | |
| 10 | + - External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND) | |
| 11 | + - I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers | |
| 12 | + - LCD controller & Camera interface | |
| 13 | + - Cryptographic processor | |
| 14 | + | |
| 15 | + Resources | |
| 16 | + --------- | |
| 17 | + Datasheet and reference manual are publicly available on ST website: | |
| 18 | + - http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013 | |
| 19 | + | |
| 20 | + Document Author | |
| 21 | + --------------- | |
| 22 | + Maxime Coquelin <mcoquelin.stm32@gmail.com> | |
| @@ -188,6 +188,7 @@ nodes to be present and contain the properties described below. · 187 unmodified lines | ||
| 188 | 188 | # On ARM 32-bit systems this property is optional and |
| 189 | 189 | can be one of: |
| 190 | 190 | "allwinner,sun6i-a31" |
| 191 | + "allwinner,sun8i-a23" | |
| 191 | 192 | "arm,psci" |
| 192 | 193 | "brcm,brahma-b15" |
| 193 | 194 | "marvell,armada-375-smp" |
| @@ -19,9 +19,10 @@ Optional Properties: · 18 unmodified lines | ||
| 19 | 19 | domains. |
| 20 | 20 | - clock-names: The following clocks can be specified: |
| 21 | 21 | - oscclk: Oscillator clock. |
| 22 | − - pclkN, clkN: Pairs of parent of input clock and input clock to the | |
| 23 | − devices in this power domain. Maximum of 4 pairs (N = 0 to 3) | |
| 24 | − are supported currently. | |
| 22 | + - clkN: Input clocks to the devices in this power domain. These clocks | |
| 23 | + will be reparented to oscclk before swithing power domain off. | |
| 24 | + Their original parent will be brought back after turning on | |
| 25 | + the domain. Maximum of 4 clocks (N = 0 to 3) are supported. | |
| 25 | 26 | - asbN: Clocks required by asynchronous bridges (ASB) present in |
| 26 | 27 | the power domain. These clock should be enabled during power |
| 27 | 28 | domain on/off operations. |
| @@ -81,12 +81,15 @@ Freescale Vybrid Platform Device Tree Bindings · 80 unmodified lines | ||
| 81 | 81 | For the Vybrid SoC familiy all variants with DDR controller are supported, |
| 82 | 82 | which is the VF5xx and VF6xx series. Out of historical reasons, in most |
| 83 | 83 | places the kernel uses vf610 to refer to the whole familiy. |
| 84 | +The compatible string "fsl,vf610m4" is used for the secondary Cortex-M4 | |
| 85 | +core support. | |
| 84 | 86 | |
| 85 | 87 | Required root node compatible property (one of them): |
| 86 | 88 | - compatible = "fsl,vf500"; |
| 87 | 89 | - compatible = "fsl,vf510"; |
| 88 | 90 | - compatible = "fsl,vf600"; |
| 89 | 91 | - compatible = "fsl,vf610"; |
| 92 | + - compatible = "fsl,vf610m4"; | |
| 90 | 93 | |
| 91 | 94 | Freescale LS1021A Platform Device Tree Bindings |
| 92 | 95 | ------------------------------------------------ |
| @@ -0,0 +1,15 @@ | ||
| 1 | +ZTE platforms device tree bindings | |
| 2 | +--------------------------------------- | |
| 3 | + | |
| 4 | +- ZX296702 board: | |
| 5 | + Required root node properties: | |
| 6 | + - compatible = "zte,zx296702-ad1", "zte,zx296702" | |
| 7 | + | |
| 8 | +System management required properties: | |
| 9 | + - compatible = "zte,sysctrl" | |
| 10 | + | |
| 11 | +Low power management required properties: | |
| 12 | + - compatible = "zte,zx296702-pcu" | |
| 13 | + | |
| 14 | +Bus matrix required properties: | |
| 15 | + - compatible = "zte,zx-bus-matrix" | |
| @@ -0,0 +1,35 @@ | ||
| 1 | +Device Tree Clock bindings for ZTE zx296702 | |
| 2 | + | |
| 3 | +This binding uses the common clock binding[1]. | |
| 4 | + | |
| 5 | +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt | |
| 6 | + | |
| 7 | +Required properties: | |
| 8 | +- compatible : shall be one of the following: | |
| 9 | + "zte,zx296702-topcrm-clk": | |
| 10 | + zx296702 top clock selection, divider and gating | |
| 11 | + | |
| 12 | + "zte,zx296702-lsp0crpm-clk" and | |
| 13 | + "zte,zx296702-lsp1crpm-clk": | |
| 14 | + zx296702 device level clock selection and gating | |
| 15 | + | |
| 16 | +- reg: Address and length of the register set | |
| 17 | + | |
| 18 | +The clock consumer should specify the desired clock by having the clock | |
| 19 | +ID in its "clocks" phandle cell. See include/dt-bindings/clock/zx296702-clock.h | |
| 20 | +for the full list of zx296702 clock IDs. | |
| 21 | + | |
| 22 | + | |
| 23 | +topclk: topcrm@0x09800000 { | |
| 24 | + compatible = "zte,zx296702-topcrm-clk"; | |
| 25 | + reg = <0x09800000 0x1000>; | |
| 26 | + #clock-cells = <1>; | |
| 27 | +}; | |
| 28 | + | |
| 29 | +uart0: serial@0x09405000 { | |
| 30 | + compatible = "zte,zx296702-uart"; | |
| 31 | + reg = <0x09405000 0x1000>; | |
| 32 | + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; | |
| 33 | + clocks = <&lsp1clk ZX296702_UART0_PCLK>; | |
| 34 | + status = "disabled"; | |
| 35 | +}; | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | * ARM AMBA Primecell PL011 serial UART |
| 2 | 2 | |
| 3 | 3 | Required properties: |
| 4 | −- compatible: must be "arm,primecell", "arm,pl011" | |
| 4 | +- compatible: must be "arm,primecell", "arm,pl011", "zte,zx296702-uart" | |
| 5 | 5 | - reg: exactly one register range with length 0x1000 |
| 6 | 6 | - interrupts: exactly one interrupt specifier |
| 7 | 7 | |
| @@ -214,3 +214,4 @@ xillybus Xillybus Ltd. · 213 unmodified lines | ||
| 214 | 214 | xlnx Xilinx |
| 215 | 215 | zyxel ZyXEL Communications Corp. |
| 216 | 216 | zarlink Zarlink Semiconductor |
| 217 | +zte ZTE Corp. | |
| @@ -1043,7 +1043,7 @@ F: arch/arm/include/asm/hardware/dec21285.h · 1042 unmodified lines | ||
| 1043 | 1043 | F: arch/arm/mach-footbridge/ |
| 1044 | 1044 | |
| 1045 | 1045 | ARM/FREESCALE IMX / MXC ARM ARCHITECTURE |
| 1046 | −M: Shawn Guo <shawn.guo@linaro.org> | |
| 1046 | +M: Shawn Guo <shawnguo@kernel.org> | |
| 1047 | 1047 | M: Sascha Hauer <kernel@pengutronix.de> |
| 1048 | 1048 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1049 | 1049 | S: Maintained |
| @@ -1052,9 +1052,11 @@ F: arch/arm/mach-imx/ · 2 unmodified lines | ||
| 1052 | 1052 | F: arch/arm/mach-mxs/ |
| 1053 | 1053 | F: arch/arm/boot/dts/imx* |
| 1054 | 1054 | F: arch/arm/configs/imx*_defconfig |
| 1055 | +F: drivers/clk/imx/ | |
| 1056 | +F: include/soc/imx/ | |
| 1055 | 1057 | |
| 1056 | 1058 | ARM/FREESCALE VYBRID ARM ARCHITECTURE |
| 1057 | −M: Shawn Guo <shawn.guo@linaro.org> | |
| 1059 | +M: Shawn Guo <shawnguo@kernel.org> | |
| 1058 | 1060 | M: Sascha Hauer <kernel@pengutronix.de> |
| 1059 | 1061 | R: Stefan Agner <stefan@agner.ch> |
| 1060 | 1062 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -1197,6 +1199,12 @@ M: Lennert Buytenhek <kernel@wantstofly.org> · 136 unmodified lines | ||
| 1197 | 1199 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1198 | 1200 | S: Maintained |
| 1199 | 1201 | |
| 1202 | +ARM/LPC18XX ARCHITECTURE | |
| 1203 | +M: Joachim Eastwood <manabian@gmail.com> | |
| 1204 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 1205 | +S: Maintained | |
| 1206 | +N: lpc18xx | |
| 1207 | + | |
| 1200 | 1208 | ARM/MAGICIAN MACHINE SUPPORT |
| 1201 | 1209 | M: Philipp Zabel <philipp.zabel@gmail.com> |
| 1202 | 1210 | S: Maintained |
| @@ -1400,6 +1408,7 @@ L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) · 197 unmodified lines | ||
| 1400 | 1408 | S: Maintained |
| 1401 | 1409 | F: arch/arm/boot/dts/s3c* |
| 1402 | 1410 | F: arch/arm/boot/dts/exynos* |
| 1411 | +F: arch/arm64/boot/dts/exynos/ | |
| 1403 | 1412 | F: arch/arm/plat-samsung/ |
| 1404 | 1413 | F: arch/arm/mach-s3c24*/ |
| 1405 | 1414 | F: arch/arm/mach-s3c64xx/ |
| @@ -1511,6 +1520,14 @@ F: drivers/usb/host/ohci-st.c · 105 unmodified lines | ||
| 1511 | 1520 | F: drivers/watchdog/st_lpc_wdt.c |
| 1512 | 1521 | F: drivers/ata/ahci_st.c |
| 1513 | 1522 | |
| 1523 | +ARM/STM32 ARCHITECTURE | |
| 1524 | +M: Maxime Coquelin <mcoquelin.stm32@gmail.com> | |
| 1525 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 1526 | +S: Maintained | |
| 1527 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32.git | |
| 1528 | +N: stm32 | |
| 1529 | +F: drivers/clocksource/armv7m_systick.c | |
| 1530 | + | |
| 1514 | 1531 | ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT |
| 1515 | 1532 | M: Lennert Buytenhek <kernel@wantstofly.org> |
| 1516 | 1533 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -1557,6 +1574,13 @@ F: drivers/rtc/rtc-ab3100.c · 40 unmodified lines | ||
| 1557 | 1574 | F: drivers/rtc/rtc-coh901331.c |
| 1558 | 1575 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git |
| 1559 | 1576 | |
| 1577 | +ARM/UNIPHIER ARCHITECTURE | |
| 1578 | +M: Masahiro Yamada <yamada.masahiro@socionext.com> | |
| 1579 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 1580 | +S: Maintained | |
| 1581 | +F: arch/arm/mach-uniphier/ | |
| 1582 | +N: uniphier | |
| 1583 | + | |
| 1560 | 1584 | ARM/Ux500 ARM ARCHITECTURE |
| 1561 | 1585 | M: Linus Walleij <linus.walleij@linaro.org> |
| 1562 | 1586 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -1634,6 +1658,15 @@ S: Maintained · 71 unmodified lines | ||
| 1634 | 1658 | F: arch/arm/mach-pxa/z2.c |
| 1635 | 1659 | F: arch/arm/mach-pxa/include/mach/z2.h |
| 1636 | 1660 | |
| 1661 | +ARM/ZTE ARCHITECTURE | |
| 1662 | +M: Jun Nie <jun.nie@linaro.org> | |
| 1663 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 1664 | +S: Maintained | |
| 1665 | +F: arch/arm/mach-zx/ | |
| 1666 | +F: drivers/clk/zte/ | |
| 1667 | +F: Documentation/devicetree/bindings/arm/zte.txt | |
| 1668 | +F: Documentation/devicetree/bindings/clock/zx296702-clk.txt | |
| 1669 | + | |
| 1637 | 1670 | ARM/ZYNQ ARCHITECTURE |
| 1638 | 1671 | M: Michal Simek <michal.simek@xilinx.com> |
| 1639 | 1672 | R: Sören Brinkmann <soren.brinkmann@xilinx.com> |
| @@ -2228,6 +2261,7 @@ S: Maintained · 588 unmodified lines | ||
| 2228 | 2261 | F: arch/arm/mach-bcm/*brcmstb* |
| 2229 | 2262 | F: arch/arm/boot/dts/bcm7*.dts* |
| 2230 | 2263 | F: drivers/bus/brcmstb_gisb.c |
| 2264 | +N: brcmstb | |
| 2231 | 2265 | |
| 2232 | 2266 | BROADCOM BMIPS MIPS ARCHITECTURE |
| 2233 | 2267 | M: Kevin Cernekee <cernekee@gmail.com> |
| @@ -331,6 +331,20 @@ config ARCH_MULTIPLATFORM · 330 unmodified lines | ||
| 331 | 331 | select SPARSE_IRQ |
| 332 | 332 | select USE_OF |
| 333 | 333 | |
| 334 | +config ARM_SINGLE_ARMV7M | |
| 335 | + bool "ARMv7-M based platforms (Cortex-M0/M3/M4)" | |
| 336 | + depends on !MMU | |
| 337 | + select ARCH_WANT_OPTIONAL_GPIOLIB | |
| 338 | + select ARM_NVIC | |
| 339 | + select AUTO_ZRELADDR | |
| 340 | + select CLKSRC_OF | |
| 341 | + select COMMON_CLK | |
| 342 | + select CPU_V7M | |
| 343 | + select GENERIC_CLOCKEVENTS | |
| 344 | + select NO_IOPORT_MAP | |
| 345 | + select SPARSE_IRQ | |
| 346 | + select USE_OF | |
| 347 | + | |
| 334 | 348 | config ARCH_REALVIEW |
| 335 | 349 | bool "ARM Ltd. RealView family" |
| 336 | 350 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| @@ -400,24 +414,6 @@ config ARCH_EBSA110 · 63 unmodified lines | ||
| 400 | 414 | Ethernet interface, two PCMCIA sockets, two serial ports and a |
| 401 | 415 | parallel port. |
| 402 | 416 | |
| 403 | −config ARCH_EFM32 | |
| 404 | − bool "Energy Micro efm32" | |
| 405 | − depends on !MMU | |
| 406 | − select ARCH_REQUIRE_GPIOLIB | |
| 407 | − select ARM_NVIC | |
| 408 | − select AUTO_ZRELADDR | |
| 409 | − select CLKSRC_OF | |
| 410 | − select COMMON_CLK | |
| 411 | − select CPU_V7M | |
| 412 | − select GENERIC_CLOCKEVENTS | |
| 413 | − select NO_DMA | |
| 414 | − select NO_IOPORT_MAP | |
| 415 | − select SPARSE_IRQ | |
| 416 | − select USE_OF | |
| 417 | − help | |
| 418 | − Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko | |
| 419 | − processors. | |
| 420 | − | |
| 421 | 417 | config ARCH_EP93XX |
| 422 | 418 | bool "EP93xx-based" |
| 423 | 419 | select ARCH_HAS_HOLES_MEMORYMODEL |
| @@ -608,6 +604,7 @@ config ARCH_PXA · 184 unmodified lines | ||
| 608 | 604 | select ARCH_REQUIRE_GPIOLIB |
| 609 | 605 | select ARM_CPU_SUSPEND if PM |
| 610 | 606 | select AUTO_ZRELADDR |
| 607 | + select COMMON_CLK | |
| 611 | 608 | select CLKDEV_LOOKUP |
| 612 | 609 | select CLKSRC_MMIO |
| 613 | 610 | select CLKSRC_OF |
| @@ -754,8 +751,10 @@ config ARCH_OMAP1 · 140 unmodified lines | ||
| 754 | 751 | select GENERIC_IRQ_CHIP |
| 755 | 752 | select HAVE_IDE |
| 756 | 753 | select IRQ_DOMAIN |
| 754 | + select MULTI_IRQ_HANDLER | |
| 757 | 755 | select NEED_MACH_IO_H if PCCARD |
| 758 | 756 | select NEED_MACH_MEMORY_H |
| 757 | + select SPARSE_IRQ | |
| 759 | 758 | help |
| 760 | 759 | Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx) |
| 761 | 760 | |
| @@ -939,6 +938,8 @@ source "arch/arm/mach-tegra/Kconfig" · 177 unmodified lines | ||
| 939 | 938 | |
| 940 | 939 | source "arch/arm/mach-u300/Kconfig" |
| 941 | 940 | |
| 941 | +source "arch/arm/mach-uniphier/Kconfig" | |
| 942 | + | |
| 942 | 943 | source "arch/arm/mach-ux500/Kconfig" |
| 943 | 944 | |
| 944 | 945 | source "arch/arm/mach-versatile/Kconfig" |
| @@ -950,8 +951,40 @@ source "arch/arm/mach-vt8500/Kconfig" · 5 unmodified lines | ||
| 950 | 951 | |
| 951 | 952 | source "arch/arm/mach-w90x900/Kconfig" |
| 952 | 953 | |
| 954 | +source "arch/arm/mach-zx/Kconfig" | |
| 955 | + | |
| 953 | 956 | source "arch/arm/mach-zynq/Kconfig" |
| 954 | 957 | |
| 958 | +# ARMv7-M architecture | |
| 959 | +config ARCH_EFM32 | |
| 960 | + bool "Energy Micro efm32" | |
| 961 | + depends on ARM_SINGLE_ARMV7M | |
| 962 | + select ARCH_REQUIRE_GPIOLIB | |
| 963 | + help | |
| 964 | + Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko | |
| 965 | + processors. | |
| 966 | + | |
| 967 | +config ARCH_LPC18XX | |
| 968 | + bool "NXP LPC18xx/LPC43xx" | |
| 969 | + depends on ARM_SINGLE_ARMV7M | |
| 970 | + select ARCH_HAS_RESET_CONTROLLER | |
| 971 | + select ARM_AMBA | |
| 972 | + select CLKSRC_LPC32XX | |
| 973 | + select PINCTRL | |
| 974 | + help | |
| 975 | + Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4 | |
| 976 | + high performance microcontrollers. | |
| 977 | + | |
| 978 | +config ARCH_STM32 | |
| 979 | + bool "STMicrolectronics STM32" | |
| 980 | + depends on ARM_SINGLE_ARMV7M | |
| 981 | + select ARCH_HAS_RESET_CONTROLLER | |
| 982 | + select ARMV7M_SYSTICK | |
| 983 | + select CLKSRC_STM32 | |
| 984 | + select RESET_CONTROLLER | |
| 985 | + help | |
| 986 | + Support for STMicroelectronics STM32 processors. | |
| 987 | + | |
| 955 | 988 | # Definitions to make life easier |
| 956 | 989 | config ARCH_ACORN |
| 957 | 990 | bool |
| @@ -1479,7 +1512,8 @@ config ARM_PSCI · 521 unmodified lines | ||
| 1479 | 1512 | # selected platforms. |
| 1480 | 1513 | config ARCH_NR_GPIO |
| 1481 | 1514 | int |
| 1482 | − default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ | |
| 1515 | + default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \ | |
| 1516 | + ARCH_ZYNQ | |
| 1483 | 1517 | default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \ |
| 1484 | 1518 | SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210 |
| 1485 | 1519 | default 416 if ARCH_SUNXI |
| @@ -410,6 +410,13 @@ choice · 409 unmodified lines | ||
| 410 | 410 | Say Y here if you want kernel low-level debugging support |
| 411 | 411 | on i.MX6SX. |
| 412 | 412 | |
| 413 | + config DEBUG_IMX7D_UART | |
| 414 | + bool "i.MX7D Debug UART" | |
| 415 | + depends on SOC_IMX7D | |
| 416 | + help | |
| 417 | + Say Y here if you want kernel low-level debugging support | |
| 418 | + on i.MX7D. | |
| 419 | + | |
| 413 | 420 | config DEBUG_KEYSTONE_UART0 |
| 414 | 421 | bool "Kernel low-level debugging on KEYSTONE2 using UART0" |
| 415 | 422 | depends on ARCH_KEYSTONE |
| @@ -433,6 +440,14 @@ choice · 17 unmodified lines | ||
| 433 | 440 | Say Y here if you want kernel low-level debugging support |
| 434 | 441 | on KS8695. |
| 435 | 442 | |
| 443 | + config DEBUG_LPC18XX_UART0 | |
| 444 | + bool "Kernel low-level debugging via LPC18xx/43xx UART0" | |
| 445 | + depends on ARCH_LPC18XX | |
| 446 | + select DEBUG_UART_8250 | |
| 447 | + help | |
| 448 | + Say Y here if you want kernel low-level debugging support | |
| 449 | + on NXP LPC18xx/43xx UART0. | |
| 450 | + | |
| 436 | 451 | config DEBUG_MESON_UARTAO |
| 437 | 452 | bool "Kernel low-level debugging via Meson6 UARTAO" |
| 438 | 453 | depends on ARCH_MESON |
| @@ -908,13 +923,22 @@ choice · 469 unmodified lines | ||
| 908 | 923 | on SA-11x0 UART ports. The kernel will check for the first |
| 909 | 924 | enabled UART in a sequence 3-1-2. |
| 910 | 925 | |
| 911 | − config DEBUG_SOCFPGA_UART | |
| 926 | + config DEBUG_SOCFPGA_UART0 | |
| 927 | + depends on ARCH_SOCFPGA | |
| 928 | + bool "Use SOCFPGA UART0 for low-level debug" | |
| 929 | + select DEBUG_UART_8250 | |
| 930 | + help | |
| 931 | + Say Y here if you want kernel low-level debugging support | |
| 932 | + on SOCFPGA(Cyclone 5 and Arria 5) based platforms. | |
| 933 | + | |
| 934 | + config DEBUG_SOCFPGA_UART1 | |
| 912 | 935 | depends on ARCH_SOCFPGA |
| 913 | − bool "Use SOCFPGA UART for low-level debug" | |
| 936 | + bool "Use SOCFPGA UART1 for low-level debug" | |
| 914 | 937 | select DEBUG_UART_8250 |
| 915 | 938 | help |
| 916 | 939 | Say Y here if you want kernel low-level debugging support |
| 917 | − on SOCFPGA based platforms. | |
| 940 | + on SOCFPGA(Arria 10) based platforms. | |
| 941 | + | |
| 918 | 942 | |
| 919 | 943 | config DEBUG_SUN9I_UART0 |
| 920 | 944 | bool "Kernel low-level debugging messages via sun9i UART0" |
| @@ -1157,6 +1181,18 @@ choice · 236 unmodified lines | ||
| 1157 | 1181 | For more details about semihosting, please see |
| 1158 | 1182 | chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd. |
| 1159 | 1183 | |
| 1184 | + config DEBUG_ZTE_ZX | |
| 1185 | + bool "Use ZTE ZX UART" | |
| 1186 | + select DEBUG_UART_PL01X | |
| 1187 | + depends on ARCH_ZX | |
| 1188 | + help | |
| 1189 | + Say Y here if you are enabling ZTE ZX296702 SOC and need | |
| 1190 | + debug uart support. | |
| 1191 | + | |
| 1192 | + This option is preferred over the platform specific | |
| 1193 | + options; the platform specific options are deprecated | |
| 1194 | + and will be soon removed. | |
| 1195 | + | |
| 1160 | 1196 | config DEBUG_LL_UART_8250 |
| 1161 | 1197 | bool "Kernel low-level debugging via 8250 UART" |
| 1162 | 1198 | help |
| @@ -1231,7 +1267,8 @@ config DEBUG_IMX_UART_PORT · 68 unmodified lines | ||
| 1231 | 1267 | DEBUG_IMX53_UART || \ |
| 1232 | 1268 | DEBUG_IMX6Q_UART || \ |
| 1233 | 1269 | DEBUG_IMX6SL_UART || \ |
| 1234 | − DEBUG_IMX6SX_UART | |
| 1270 | + DEBUG_IMX6SX_UART || \ | |
| 1271 | + DEBUG_IMX7D_UART | |
| 1235 | 1272 | default 1 |
| 1236 | 1273 | depends on ARCH_MXC |
| 1237 | 1274 | help |
| @@ -1281,7 +1318,8 @@ config DEBUG_LL_INCLUDE · 43 unmodified lines | ||
| 1281 | 1318 | DEBUG_IMX53_UART ||\ |
| 1282 | 1319 | DEBUG_IMX6Q_UART || \ |
| 1283 | 1320 | DEBUG_IMX6SL_UART || \ |
| 1284 | − DEBUG_IMX6SX_UART | |
| 1321 | + DEBUG_IMX6SX_UART || \ | |
| 1322 | + DEBUG_IMX7D_UART | |
| 1285 | 1323 | default "debug/ks8695.S" if DEBUG_KS8695_UART |
| 1286 | 1324 | default "debug/msm.S" if DEBUG_QCOM_UARTDM |
| 1287 | 1325 | default "debug/netx.S" if DEBUG_NETX_UART |
| @@ -1337,6 +1375,7 @@ config DEBUG_UART_PHYS · 49 unmodified lines | ||
| 1337 | 1375 | default 0x02531000 if DEBUG_KEYSTONE_UART1 |
| 1338 | 1376 | default 0x03010fe0 if ARCH_RPC |
| 1339 | 1377 | default 0x07000000 if DEBUG_SUN9I_UART0 |
| 1378 | + default 0x09405000 if DEBUG_ZTE_ZX | |
| 1340 | 1379 | default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \ |
| 1341 | 1380 | DEBUG_VEXPRESS_UART0_CA9 |
| 1342 | 1381 | default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT |
| @@ -1359,6 +1398,7 @@ config DEBUG_UART_PHYS · 16 unmodified lines | ||
| 1359 | 1398 | default 0x20201000 if DEBUG_BCM2835 |
| 1360 | 1399 | default 0x3e000000 if DEBUG_BCM_KONA_UART |
| 1361 | 1400 | default 0x4000e400 if DEBUG_LL_UART_EFM32 |
| 1401 | + default 0x40081000 if DEBUG_LPC18XX_UART0 | |
| 1362 | 1402 | default 0x40090000 if ARCH_LPC32XX |
| 1363 | 1403 | default 0x40100000 if DEBUG_PXA_UART1 |
| 1364 | 1404 | default 0x42000000 if ARCH_GEMINI |
| @@ -1407,7 +1447,8 @@ config DEBUG_UART_PHYS · 42 unmodified lines | ||
| 1407 | 1447 | default 0xfd883000 if DEBUG_ALPINE_UART0 |
| 1408 | 1448 | default 0xfe800000 if ARCH_IOP32X |
| 1409 | 1449 | default 0xff690000 if DEBUG_RK32_UART2 |
| 1410 | − default 0xffc02000 if DEBUG_SOCFPGA_UART | |
| 1450 | + default 0xffc02000 if DEBUG_SOCFPGA_UART0 | |
| 1451 | + default 0xffc02100 if DEBUG_SOCFPGA_UART1 | |
| 1411 | 1452 | default 0xffd82340 if ARCH_IOP13XX |
| 1412 | 1453 | default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0 |
| 1413 | 1454 | default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2 |
| @@ -1466,6 +1507,7 @@ config DEBUG_UART_VIRT · 52 unmodified lines | ||
| 1466 | 1507 | default 0xfb009000 if DEBUG_REALVIEW_STD_PORT |
| 1467 | 1508 | default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT |
| 1468 | 1509 | default 0xfc40ab00 if DEBUG_BRCMSTB_UART |
| 1510 | + default 0xfc705000 if DEBUG_ZTE_ZX | |
| 1469 | 1511 | default 0xfcfe8600 if DEBUG_UART_BCM63XX |
| 1470 | 1512 | default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX |
| 1471 | 1513 | default 0xfd000000 if ARCH_SPEAR13XX |
| @@ -1485,7 +1527,8 @@ config DEBUG_UART_VIRT · 13 unmodified lines | ||
| 1485 | 1527 | default 0xfeb26000 if DEBUG_RK3X_UART1 |
| 1486 | 1528 | default 0xfeb30c00 if DEBUG_KEYSTONE_UART0 |
| 1487 | 1529 | default 0xfeb31000 if DEBUG_KEYSTONE_UART1 |
| 1488 | − default 0xfec02000 if DEBUG_SOCFPGA_UART | |
| 1530 | + default 0xfec02000 if DEBUG_SOCFPGA_UART0 | |
| 1531 | + default 0xfec02100 if DEBUG_SOCFPGA_UART1 | |
| 1489 | 1532 | default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE |
| 1490 | 1533 | default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE |
| 1491 | 1534 | default 0xfec10000 if DEBUG_SIRFATLAS7_UART0 |
| @@ -1530,8 +1573,9 @@ config DEBUG_UART_8250_WORD · 38 unmodified lines | ||
| 1530 | 1573 | bool "Use 32-bit accesses for 8250 UART" |
| 1531 | 1574 | depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 |
| 1532 | 1575 | depends on DEBUG_UART_8250_SHIFT >= 2 |
| 1533 | − default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \ | |
| 1534 | − ARCH_KEYSTONE || DEBUG_ALPINE_UART0 || \ | |
| 1576 | + default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART0 || \ | |
| 1577 | + DEBUG_SOCFPGA_UART1 || ARCH_KEYSTONE || \ | |
| 1578 | + DEBUG_ALPINE_UART0 || \ | |
| 1535 | 1579 | DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ |
| 1536 | 1580 | DEBUG_DAVINCI_DA8XX_UART2 || \ |
| 1537 | 1581 | DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \ |
| @@ -1544,7 +1588,7 @@ config DEBUG_UART_8250_FLOW_CONTROL · 6 unmodified lines | ||
| 1544 | 1588 | |
| 1545 | 1589 | config DEBUG_UNCOMPRESS |
| 1546 | 1590 | bool |
| 1547 | − depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG | |
| 1591 | + depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M | |
| 1548 | 1592 | default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \ |
| 1549 | 1593 | (!DEBUG_TEGRA_UART || !ZBOOT_ROM) |
| 1550 | 1594 | help |
| @@ -1561,7 +1605,7 @@ config DEBUG_UNCOMPRESS · 10 unmodified lines | ||
| 1561 | 1605 | config UNCOMPRESS_INCLUDE |
| 1562 | 1606 | string |
| 1563 | 1607 | default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \ |
| 1564 | − PLAT_SAMSUNG || ARCH_EFM32 || \ | |
| 1608 | + PLAT_SAMSUNG || ARM_SINGLE_ARMV7M || \ | |
| 1565 | 1609 | ARCH_SHMOBILE_LEGACY |
| 1566 | 1610 | default "mach/uncompress.h" |
| 1567 | 1611 | |
| @@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IOP33X) += iop33x · 166 unmodified lines | ||
| 167 | 167 | machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx |
| 168 | 168 | machine-$(CONFIG_ARCH_KEYSTONE) += keystone |
| 169 | 169 | machine-$(CONFIG_ARCH_KS8695) += ks8695 |
| 170 | +machine-$(CONFIG_ARCH_LPC18XX) += lpc18xx | |
| 170 | 171 | machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx |
| 171 | 172 | machine-$(CONFIG_ARCH_MESON) += meson |
| 172 | 173 | machine-$(CONFIG_ARCH_MMP) += mmp |
| @@ -196,14 +197,17 @@ machine-$(CONFIG_ARCH_SHMOBILE) += shmobile · 23 unmodified lines | ||
| 196 | 197 | machine-$(CONFIG_ARCH_SIRF) += prima2 |
| 197 | 198 | machine-$(CONFIG_ARCH_SOCFPGA) += socfpga |
| 198 | 199 | machine-$(CONFIG_ARCH_STI) += sti |
| 200 | +machine-$(CONFIG_ARCH_STM32) += stm32 | |
| 199 | 201 | machine-$(CONFIG_ARCH_SUNXI) += sunxi |
| 200 | 202 | machine-$(CONFIG_ARCH_TEGRA) += tegra |
| 201 | 203 | machine-$(CONFIG_ARCH_U300) += u300 |
| 202 | 204 | machine-$(CONFIG_ARCH_U8500) += ux500 |
| 205 | +machine-$(CONFIG_ARCH_UNIPHIER) += uniphier | |
| 203 | 206 | machine-$(CONFIG_ARCH_VERSATILE) += versatile |
| 204 | 207 | machine-$(CONFIG_ARCH_VEXPRESS) += vexpress |
| 205 | 208 | machine-$(CONFIG_ARCH_VT8500) += vt8500 |
| 206 | 209 | machine-$(CONFIG_ARCH_W90X900) += w90x900 |
| 210 | +machine-$(CONFIG_ARCH_ZX) += zx | |
| 207 | 211 | machine-$(CONFIG_ARCH_ZYNQ) += zynq |
| 208 | 212 | machine-$(CONFIG_PLAT_SPEAR) += spear |
| 209 | 213 | |
| @@ -660,6 +660,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ · 659 unmodified lines | ||
| 660 | 660 | mt6592-evb.dtb \ |
| 661 | 661 | mt8127-moose.dtb \ |
| 662 | 662 | mt8135-evbp1.dtb |
| 663 | +dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb | |
| 663 | 664 | endif |
| 664 | 665 | |
| 665 | 666 | always := $(dtb-y) |
| @@ -0,0 +1,48 @@ | ||
| 1 | + | |
| 2 | +/dts-v1/; | |
| 3 | + | |
| 4 | +#include "zx296702.dtsi" | |
| 5 | + | |
| 6 | +/ { | |
| 7 | + model = "ZTE ZX296702 AD1 Board"; | |
| 8 | + compatible = "zte,zx296702-ad1", "zte,zx296702"; | |
| 9 | + | |
| 10 | + aliases { | |
| 11 | + serial0 = &uart0; | |
| 12 | + serial1 = &uart1; | |
| 13 | + }; | |
| 14 | + | |
| 15 | + memory { | |
| 16 | + reg = <0x50000000 0x20000000>; | |
| 17 | + }; | |
| 18 | +}; | |
| 19 | + | |
| 20 | +&mmc0 { | |
| 21 | + num-slots = <1>; | |
| 22 | + supports-highspeed; | |
| 23 | + non-removable; | |
| 24 | + disable-wp; | |
| 25 | + status = "okay"; | |
| 26 | + | |
| 27 | + slot@0 { | |
| 28 | + reg = <0>; | |
| 29 | + bus-width = <4>; | |
| 30 | + }; | |
| 31 | +}; | |
| 32 | + | |
| 33 | +&mmc1 { | |
| 34 | + num-slots = <1>; | |
| 35 | + supports-highspeed; | |
| 36 | + non-removable; | |
| 37 | + disable-wp; | |
| 38 | + status = "okay"; | |
| 39 | + | |
| 40 | + slot@0 { | |
| 41 | + reg = <0>; | |
| 42 | + bus-width = <8>; | |
| 43 | + }; | |
| 44 | +}; | |
| 45 | + | |
| 46 | +&uart0 { | |
| 47 | + status = "okay"; | |
| 48 | +}; | |
| @@ -0,0 +1,139 @@ | ||
| 1 | + | |
| 2 | +#include "skeleton.dtsi" | |
| 3 | +#include <dt-bindings/clock/zx296702-clock.h> | |
| 4 | +#include <dt-bindings/interrupt-controller/arm-gic.h> | |
| 5 | + | |
| 6 | +/ { | |
| 7 | + cpus { | |
| 8 | + #address-cells = <1>; | |
| 9 | + #size-cells = <0>; | |
| 10 | + enable-method = "zte,zx296702-smp"; | |
| 11 | + | |
| 12 | + cpu@0 { | |
| 13 | + compatible = "arm,cortex-a9"; | |
| 14 | + device_type = "cpu"; | |
| 15 | + next-level-cache = <&l2cc>; | |
| 16 | + reg = <0>; | |
| 17 | + }; | |
| 18 | + | |
| 19 | + cpu@1 { | |
| 20 | + compatible = "arm,cortex-a9"; | |
| 21 | + device_type = "cpu"; | |
| 22 | + next-level-cache = <&l2cc>; | |
| 23 | + reg = <1>; | |
| 24 | + }; | |
| 25 | + }; | |
| 26 | + | |
| 27 | + | |
| 28 | + soc { | |
| 29 | + #address-cells = <1>; | |
| 30 | + #size-cells = <1>; | |
| 31 | + compatible = "simple-bus"; | |
| 32 | + interrupt-parent = <&intc>; | |
| 33 | + ranges; | |
| 34 | + | |
| 35 | + matrix: bus-matrix@400000 { | |
| 36 | + compatible = "zte,zx-bus-matrix"; | |
| 37 | + reg = <0x00400000 0x1000>; | |
| 38 | + }; | |
| 39 | + | |
| 40 | + intc: interrupt-controller@00801000 { | |
| 41 | + compatible = "arm,cortex-a9-gic"; | |
| 42 | + #interrupt-cells = <3>; | |
| 43 | + #address-cells = <1>; | |
| 44 | + #size-cells = <1>; | |
| 45 | + interrupt-controller; | |
| 46 | + reg = <0x00801000 0x1000>, | |
| 47 | + <0x00800100 0x100>; | |
| 48 | + }; | |
| 49 | + | |
| 50 | + global_timer: timer@008000200 { | |
| 51 | + compatible = "arm,cortex-a9-global-timer"; | |
| 52 | + reg = <0x00800200 0x20>; | |
| 53 | + interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>; | |
| 54 | + interrupt-parent = <&intc>; | |
| 55 | + clocks = <&topclk ZX296702_A9_PERIPHCLK>; | |
| 56 | + }; | |
| 57 | + | |
| 58 | + l2cc: l2-cache-controller@0x00c00000 { | |
| 59 | + compatible = "arm,pl310-cache"; | |
| 60 | + reg = <0x00c00000 0x1000>; | |
| 61 | + cache-unified; | |
| 62 | + cache-level = <2>; | |
| 63 | + arm,data-latency = <1 1 1>; | |
| 64 | + arm,tag-latency = <1 1 1>; | |
| 65 | + arm,double-linefill = <1>; | |
| 66 | + arm,double-linefill-incr = <0>; | |
| 67 | + }; | |
| 68 | + | |
| 69 | + pcu: pcu@0xa0008000 { | |
| 70 | + compatible = "zte,zx296702-pcu"; | |
| 71 | + reg = <0xa0008000 0x1000>; | |
| 72 | + }; | |
| 73 | + | |
| 74 | + topclk: topclk@0x09800000 { | |
| 75 | + compatible = "zte,zx296702-topcrm-clk"; | |
| 76 | + reg = <0x09800000 0x1000>; | |
| 77 | + #clock-cells = <1>; | |
| 78 | + }; | |
| 79 | + | |
| 80 | + lsp1clk: lsp1clk@0x09400000 { | |
| 81 | + compatible = "zte,zx296702-lsp1crpm-clk"; | |
| 82 | + reg = <0x09400000 0x1000>; | |
| 83 | + #clock-cells = <1>; | |
| 84 | + }; | |
| 85 | + | |
| 86 | + lsp0clk: lsp0clk@0x0b000000 { | |
| 87 | + compatible = "zte,zx296702-lsp0crpm-clk"; | |
| 88 | + reg = <0x0b000000 0x1000>; | |
| 89 | + #clock-cells = <1>; | |
| 90 | + }; | |
| 91 | + | |
| 92 | + uart0: serial@0x09405000 { | |
| 93 | + compatible = "zte,zx296702-uart"; | |
| 94 | + reg = <0x09405000 0x1000>; | |
| 95 | + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; | |
| 96 | + clocks = <&lsp1clk ZX296702_UART0_WCLK>; | |
| 97 | + status = "disabled"; | |
| 98 | + }; | |
| 99 | + | |
| 100 | + uart1: serial@0x09406000 { | |
| 101 | + compatible = "zte,zx296702-uart"; | |
| 102 | + reg = <0x09406000 0x1000>; | |
| 103 | + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; | |
| 104 | + clocks = <&lsp1clk ZX296702_UART1_WCLK>; | |
| 105 | + status = "disabled"; | |
| 106 | + }; | |
| 107 | + | |
| 108 | + mmc0: mmc@0x09408000 { | |
| 109 | + compatible = "snps,dw-mshc"; | |
| 110 | + #address-cells = <1>; | |
| 111 | + #size-cells = <0>; | |
| 112 | + reg = <0x09408000 0x1000>; | |
| 113 | + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; | |
| 114 | + fifo-depth = <32>; | |
| 115 | + clocks = <&lsp1clk ZX296702_SDMMC0_PCLK>, | |
| 116 | + <&lsp1clk ZX296702_SDMMC0_WCLK>; | |
| 117 | + clock-names = "biu", "ciu"; | |
| 118 | + status = "disabled"; | |
| 119 | + }; | |
| 120 | + | |
| 121 | + mmc1: mmc@0x0b003000 { | |
| 122 | + compatible = "snps,dw-mshc"; | |
| 123 | + #address-cells = <1>; | |
| 124 | + #size-cells = <0>; | |
| 125 | + reg = <0x0b003000 0x1000>; | |
| 126 | + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; | |
| 127 | + fifo-depth = <32>; | |
| 128 | + clocks = <&lsp0clk ZX296702_SDMMC1_PCLK>, | |
| 129 | + <&lsp0clk ZX296702_SDMMC1_WCLK>; | |
| 130 | + clock-names = "biu", "ciu"; | |
| 131 | + status = "disabled"; | |
| 132 | + }; | |
| 133 | + | |
| 134 | + sysctrl: sysctrl@0xa0007000 { | |
| 135 | + compatible = "zte,sysctrl", "syscon"; | |
| 136 | + reg = <0xa0007000 0x1000>; | |
| 137 | + }; | |
| 138 | + }; | |
| 139 | +}; | |
| @@ -16,6 +16,7 @@ CONFIG_EMBEDDED=y · 15 unmodified lines | ||
| 16 | 16 | # CONFIG_IOSCHED_DEADLINE is not set |
| 17 | 17 | # CONFIG_IOSCHED_CFQ is not set |
| 18 | 18 | # CONFIG_MMU is not set |
| 19 | +CONFIG_ARM_SINGLE_ARMV7M=y | |
| 19 | 20 | CONFIG_ARCH_EFM32=y |
| 20 | 21 | CONFIG_SET_MEM_PARAM=y |
| 21 | 22 | CONFIG_DRAM_BASE=0x88000000 |
| @@ -0,0 +1,129 @@ | ||
| 1 | +CONFIG_EXPERIMENTAL=y | |
| 2 | +CONFIG_SYSVIPC=y | |
| 3 | +CONFIG_NO_HZ=y | |
| 4 | +CONFIG_HIGH_RES_TIMERS=y | |
| 5 | +CONFIG_LOG_BUF_SHIFT=14 | |
| 6 | +CONFIG_CGROUPS=y | |
| 7 | +CONFIG_CGROUP_DEBUG=y | |
| 8 | +CONFIG_CGROUP_FREEZER=y | |
| 9 | +CONFIG_CGROUP_CPUACCT=y | |
| 10 | +CONFIG_RESOURCE_COUNTERS=y | |
| 11 | +CONFIG_CGROUP_SCHED=y | |
| 12 | +CONFIG_RT_GROUP_SCHED=y | |
| 13 | +CONFIG_NAMESPACES=y | |
| 14 | +CONFIG_USER_NS=y | |
| 15 | +CONFIG_BLK_DEV_INITRD=y | |
| 16 | +CONFIG_SYSCTL_SYSCALL=y | |
| 17 | +CONFIG_KALLSYMS_ALL=y | |
| 18 | +CONFIG_EMBEDDED=y | |
| 19 | +CONFIG_PERF_EVENTS=y | |
| 20 | +CONFIG_SLAB=y | |
| 21 | +# CONFIG_BLK_DEV_BSG is not set | |
| 22 | +# CONFIG_IOSCHED_CFQ is not set | |
| 23 | +CONFIG_ARCH_ZX=y | |
| 24 | +CONFIG_SOC_ZX296702=y | |
| 25 | +# CONFIG_SWP_EMULATE is not set | |
| 26 | +CONFIG_ARM_ERRATA_754322=y | |
| 27 | +CONFIG_ARM_ERRATA_775420=y | |
| 28 | +CONFIG_SMP=y | |
| 29 | +CONFIG_VMSPLIT_2G=y | |
| 30 | +CONFIG_PREEMPT=y | |
| 31 | +CONFIG_AEABI=y | |
| 32 | +CONFIG_KSM=y | |
| 33 | +# CONFIG_IOMMU_SUPPORT is not set | |
| 34 | +CONFIG_VFP=y | |
| 35 | +CONFIG_NEON=y | |
| 36 | +CONFIG_KERNEL_MODE_NEON=y | |
| 37 | +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | |
| 38 | +CONFIG_HIBERNATION=y | |
| 39 | +CONFIG_PM_RUNTIME=y | |
| 40 | +CONFIG_PM_DEBUG=y | |
| 41 | +CONFIG_SUSPEND_TIME=y | |
| 42 | +CONFIG_ZBOOT_ROM_TEXT=0x0 | |
| 43 | +CONFIG_ZBOOT_ROM_BSS=0x0 | |
| 44 | +CONFIG_CMDLINE="console=ttyAMA0,115200 debug earlyprintk root=/dev/ram rw rootwait" | |
| 45 | +#CONFIG_NET is not set | |
| 46 | +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |
| 47 | +CONFIG_DEVTMPFS=y | |
| 48 | +CONFIG_DEVTMPFS_MOUNT=y | |
| 49 | +CONFIG_DMA_CMA=y | |
| 50 | +CONFIG_CMA_SIZE_MBYTES=192 | |
| 51 | +CONFIG_BLK_DEV_LOOP=y | |
| 52 | +CONFIG_BLK_DEV_RAM=y | |
| 53 | +CONFIG_BLK_DEV_RAM_COUNT=1 | |
| 54 | +CONFIG_BLK_DEV_RAM_SIZE=8192 | |
| 55 | +CONFIG_UID_STAT=y | |
| 56 | +CONFIG_SCSI=y | |
| 57 | +CONFIG_BLK_DEV_SD=y | |
| 58 | +CONFIG_CHR_DEV_SG=y | |
| 59 | +CONFIG_CHR_DEV_SCH=y | |
| 60 | +CONFIG_SCSI_MULTI_LUN=y | |
| 61 | +CONFIG_MD=y | |
| 62 | +CONFIG_BLK_DEV_DM=y | |
| 63 | +CONFIG_DM_CRYPT=y | |
| 64 | +CONFIG_DM_UEVENT=y | |
| 65 | +CONFIG_DM_VERITY=y | |
| 66 | +CONFIG_NETDEVICES=y | |
| 67 | +# CONFIG_INPUT_MOUSE is not set | |
| 68 | +CONFIG_SERIO=y | |
| 69 | +CONFIG_SERIO_LIBPS2=y | |
| 70 | +CONFIG_SPI=y | |
| 71 | +CONFIG_LOGO=y | |
| 72 | +CONFIG_SERIAL_CORE=y | |
| 73 | +CONFIG_SERIAL_CORE_CONSOLE=y | |
| 74 | +CONFIG_CONSOLE_POLL=y | |
| 75 | +CONFIG_SERIAL_AMBA_PL011=y | |
| 76 | +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | |
| 77 | +CONFIG_SERIAL_OF_PLATFORM=y | |
| 78 | +# CONFIG_LEGACY_PTYS is not set | |
| 79 | +# CONFIG_HW_RANDOM is not set | |
| 80 | +# CONFIG_HWMON is not set | |
| 81 | +# CONFIG_USB_SUPPORT is not set | |
| 82 | +CONFIG_MMC=y | |
| 83 | +CONFIG_MMC_UNSAFE_RESUME=y | |
| 84 | +CONFIG_MMC_BLOCK_MINORS=16 | |
| 85 | +CONFIG_MMC_DW=y | |
| 86 | +CONFIG_MMC_DW_IDMAC=y | |
| 87 | +CONFIG_EXT2_FS=y | |
| 88 | +CONFIG_EXT4_FS=y | |
| 89 | +CONFIG_EXT4_FS_POSIX_ACL=y | |
| 90 | +CONFIG_EXT4_FS_SECURITY=y | |
| 91 | +CONFIG_EXT4_DEBUG=y | |
| 92 | +CONFIG_FUSE_FS=y | |
| 93 | +CONFIG_MSDOS_FS=y | |
| 94 | +CONFIG_VFAT_FS=y | |
| 95 | +CONFIG_FAT_DEFAULT_CODEPAGE=936 | |
| 96 | +CONFIG_TMPFS=y | |
| 97 | +CONFIG_TMPFS_POSIX_ACL=y | |
| 98 | +#CONFIG_NFS_FS is not set | |
| 99 | +CONFIG_NLS_CODEPAGE_936=y | |
| 100 | +CONFIG_NLS_ISO8859_1=y | |
| 101 | +CONFIG_NLS_UTF8=y | |
| 102 | +CONFIG_PRINTK_TIME=y | |
| 103 | +CONFIG_MAGIC_SYSRQ=y | |
| 104 | +CONFIG_DEBUG_KERNEL=y | |
| 105 | +CONFIG_DEBUG_INFO=y | |
| 106 | +CONFIG_FRAME_WARN=4096 | |
| 107 | +CONFIG_DEBUG_FS=y | |
| 108 | +CONFIG_DEBUG_MEMORY_INIT=y | |
| 109 | +CONFIG_PANIC_TIMEOUT=5 | |
| 110 | +# CONFIG_SCHED_DEBUG is not set | |
| 111 | +CONFIG_SCHEDSTATS=y | |
| 112 | +CONFIG_TIMER_STATS=y | |
| 113 | +CONFIG_DEBUG_RT_MUTEXES=y | |
| 114 | +CONFIG_DEBUG_SPINLOCK=y | |
| 115 | +CONFIG_DEBUG_MUTEXES=y | |
| 116 | +CONFIG_RCU_CPU_STALL_TIMEOUT=60 | |
| 117 | +# CONFIG_FTRACE is not set | |
| 118 | +CONFIG_KGDB=y | |
| 119 | +CONFIG_KGDB_KDB=y | |
| 120 | +# CONFIG_ARM_UNWIND is not set | |
| 121 | +CONFIG_DEBUG_PREEMPT=y | |
| 122 | +CONFIG_DEBUG_USER=y | |
| 123 | +CONFIG_DEBUG_LL=y | |
| 124 | +CONFIG_DYNAMIC_DEBUG=y | |
| 125 | +CONFIG_STACKTRACE=y | |
| 126 | +CONFIG_DEBUG_ZTE_ZX=y | |
| 127 | +CONFIG_EARLY_PRINTK=y | |
| 128 | +CONFIG_CRYPTO_LZO=y | |
| 129 | +CONFIG_GPIOLIB=y | |
| @@ -33,6 +33,10 @@ struct firmware_ops { · 32 unmodified lines | ||
| 33 | 33 | * Sets boot address of specified physical CPU |
| 34 | 34 | */ |
| 35 | 35 | int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr); |
| 36 | + /* | |
| 37 | + * Gets boot address of specified physical CPU | |
| 38 | + */ | |
| 39 | + int (*get_cpu_boot_addr)(int cpu, unsigned long *boot_addr); | |
| 36 | 40 | /* |
| 37 | 41 | * Boots specified physical CPU |
| 38 | 42 | */ |
| @@ -5,6 +5,9 @@ · 4 unmodified lines | ||
| 5 | 5 | * First, the standard VFP set. |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | +#ifndef __ASM_VFP_H | |
| 9 | +#define __ASM_VFP_H | |
| 10 | + | |
| 8 | 11 | #define FPSID cr0 |
| 9 | 12 | #define FPSCR cr1 |
| 10 | 13 | #define MVFR1 cr6 |
| @@ -87,3 +90,9 @@ · 76 unmodified lines | ||
| 87 | 90 | #define VFPOPDESC_UNUSED_BIT (24) |
| 88 | 91 | #define VFPOPDESC_UNUSED_MASK (0xFF << VFPOPDESC_UNUSED_BIT) |
| 89 | 92 | #define VFPOPDESC_OPDESC_MASK (~(VFPOPDESC_LENGTH_MASK | VFPOPDESC_UNUSED_MASK)) |
| 93 | + | |
| 94 | +#ifndef __ASSEMBLY__ | |
| 95 | +void vfp_disable(void); | |
| 96 | +#endif | |
| 97 | + | |
| 98 | +#endif /* __ASM_VFP_H */ | |
| @@ -16,11 +16,14 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | #ifdef CONFIG_DEBUG_UART_8250_WORD |
| 18 | 18 | .macro store, rd, rx:vararg |
| 19 | + ARM_BE8(rev \rd, \rd) | |
| 19 | 20 | str \rd, \rx |
| 21 | + ARM_BE8(rev \rd, \rd) | |
| 20 | 22 | .endm |
| 21 | 23 | |
| 22 | 24 | .macro load, rd, rx:vararg |
| 23 | 25 | ldr \rd, \rx |
| 26 | + ARM_BE8(rev \rd, \rd) | |
| 24 | 27 | .endm |
| 25 | 28 | #else |
| 26 | 29 | .macro store, rd, rx:vararg |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | #define UARTn_TXDATA 0x0034 |
| 18 | 18 | |
| 19 | − .macro addruart, rx, tmp | |
| 19 | + .macro addruart, rx, tmp, tmp2 | |
| 20 | 20 | ldr \rx, =(CONFIG_DEBUG_UART_PHYS) |
| 21 | 21 | |
| 22 | 22 | /* |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | − * Copyright (C) 2012 Freescale Semiconductor, Inc. | |
| 2 | + * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. | |
| 3 | 3 | * |
| 4 | 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | 5 | * it under the terms of the GNU General Public License version 2 as |
| @@ -90,6 +90,16 @@ · 84 unmodified lines | ||
| 90 | 90 | #define IMX6SX_UART_BASE_ADDR(n) IMX6SX_UART##n##_BASE_ADDR |
| 91 | 91 | #define IMX6SX_UART_BASE(n) IMX6SX_UART_BASE_ADDR(n) |
| 92 | 92 | |
| 93 | +#define IMX7D_UART1_BASE_ADDR 0x30860000 | |
| 94 | +#define IMX7D_UART2_BASE_ADDR 0x30890000 | |
| 95 | +#define IMX7D_UART3_BASE_ADDR 0x30880000 | |
| 96 | +#define IMX7D_UART4_BASE_ADDR 0x30a60000 | |
| 97 | +#define IMX7D_UART5_BASE_ADDR 0x30a70000 | |
| 98 | +#define IMX7D_UART6_BASE_ADDR 0x30a80000 | |
| 99 | +#define IMX7D_UART7_BASE_ADDR 0x30a90000 | |
| 100 | +#define IMX7D_UART_BASE_ADDR(n) IMX7D_UART##n##_BASE_ADDR | |
| 101 | +#define IMX7D_UART_BASE(n) IMX7D_UART_BASE_ADDR(n) | |
| 102 | + | |
| 93 | 103 | #define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT) |
| 94 | 104 | |
| 95 | 105 | #ifdef CONFIG_DEBUG_IMX1_UART |
| @@ -114,6 +124,9 @@ · 18 unmodified lines | ||
| 114 | 124 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SL) |
| 115 | 125 | #elif defined(CONFIG_DEBUG_IMX6SX_UART) |
| 116 | 126 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SX) |
| 127 | +#elif defined(CONFIG_DEBUG_IMX7D_UART) | |
| 128 | +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX7D) | |
| 129 | + | |
| 117 | 130 | #endif |
| 118 | 131 | |
| 119 | 132 | #endif /* __DEBUG_IMX_UART_H */ |
| @@ -12,6 +12,13 @@ · 11 unmodified lines | ||
| 12 | 12 | */ |
| 13 | 13 | #include <linux/amba/serial.h> |
| 14 | 14 | |
| 15 | +#ifdef CONFIG_DEBUG_ZTE_ZX | |
| 16 | +#undef UART01x_DR | |
| 17 | +#undef UART01x_FR | |
| 18 | +#define UART01x_DR 0x04 | |
| 19 | +#define UART01x_FR 0x14 | |
| 20 | +#endif | |
| 21 | + | |
| 15 | 22 | #ifdef CONFIG_DEBUG_UART_PHYS |
| 16 | 23 | .macro addruart, rp, rv, tmp |
| 17 | 24 | ldr \rp, =CONFIG_DEBUG_UART_PHYS |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | #else /* !CONFIG_MMU */ |
| 37 | 37 | .macro addruart_current, rx, tmp1, tmp2 |
| 38 | − addruart \rx, \tmp1 | |
| 38 | + addruart \rx, \tmp1, \tmp2 | |
| 39 | 39 | .endm |
| 40 | 40 | |
| 41 | 41 | #endif /* CONFIG_MMU */ |
| @@ -19,6 +19,7 @@ config ARCH_BCM_IPROC · 18 unmodified lines | ||
| 19 | 19 | select ARCH_REQUIRE_GPIOLIB |
| 20 | 20 | select ARM_AMBA |
| 21 | 21 | select PINCTRL |
| 22 | + select MTD_NAND_BRCMNAND | |
| 22 | 23 | help |
| 23 | 24 | This enables support for systems based on Broadcom IPROC architected SoCs. |
| 24 | 25 | The IPROC complex contains one or more ARM CPUs along with common |
| @@ -144,6 +145,7 @@ config ARCH_BRCMSTB · 119 unmodified lines | ||
| 144 | 145 | select BRCMSTB_GISB_ARB |
| 145 | 146 | select BRCMSTB_L2_IRQ |
| 146 | 147 | select BCM7120_L2_IRQ |
| 148 | + select ARCH_WANT_OPTIONAL_GPIOLIB | |
| 147 | 149 | help |
| 148 | 150 | Say Y if you intend to run the kernel on a Broadcom ARM-based STB |
| 149 | 151 | chipset. |
| @@ -38,7 +38,12 @@ obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o · 37 unmodified lines | ||
| 38 | 38 | obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o |
| 39 | 39 | |
| 40 | 40 | # BCM63XXx |
| 41 | −obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o | |
| 41 | +ifeq ($(CONFIG_ARCH_BCM_63XX),y) | |
| 42 | +CFLAGS_bcm63xx_headsmp.o += -march=armv7-a | |
| 43 | +obj-y += bcm63xx.o | |
| 44 | +obj-$(CONFIG_SMP) += bcm63xx_smp.o bcm63xx_headsmp.o \ | |
| 45 | + bcm63xx_pmb.o | |
| 46 | +endif | |
| 42 | 47 | |
| 43 | 48 | ifeq ($(CONFIG_ARCH_BRCMSTB),y) |
| 44 | 49 | CFLAGS_platsmp-brcmstb.o += -march=armv7-a |
| @@ -0,0 +1,23 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015, Broadcom Corporation | |
| 3 | + * All Rights Reserved | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | +#include <linux/linkage.h> | |
| 10 | +#include <linux/init.h> | |
| 11 | +#include <asm/assembler.h> | |
| 12 | + | |
| 13 | +ENTRY(bcm63138_secondary_startup) | |
| 14 | + ARM_BE8(setend be) | |
| 15 | + /* | |
| 16 | + * L1 cache does have unpredictable contents at power-up clean its | |
| 17 | + * contents without flushing | |
| 18 | + */ | |
| 19 | + bl v7_invalidate_l1 | |
| 20 | + nop | |
| 21 | + | |
| 22 | + b secondary_startup | |
| 23 | +ENDPROC(bcm63138_secondary_startup) | |
| @@ -0,0 +1,221 @@ | ||
| 1 | +/* | |
| 2 | + * Broadcom BCM63138 PMB initialization for secondary CPU(s) | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015 Broadcom Corporation | |
| 5 | + * Author: Florian Fainelli <f.fainelli@gmail.com> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + */ | |
| 12 | +#include <linux/kernel.h> | |
| 13 | +#include <linux/io.h> | |
| 14 | +#include <linux/spinlock.h> | |
| 15 | +#include <linux/reset/bcm63xx_pmb.h> | |
| 16 | +#include <linux/of.h> | |
| 17 | +#include <linux/of_address.h> | |
| 18 | + | |
| 19 | +#include "bcm63xx_smp.h" | |
| 20 | + | |
| 21 | +/* ARM Control register definitions */ | |
| 22 | +#define CORE_PWR_CTRL_SHIFT 0 | |
| 23 | +#define CORE_PWR_CTRL_MASK 0x3 | |
| 24 | +#define PLL_PWR_ON BIT(8) | |
| 25 | +#define PLL_LDO_PWR_ON BIT(9) | |
| 26 | +#define PLL_CLAMP_ON BIT(10) | |
| 27 | +#define CPU_RESET_N(x) BIT(13 + (x)) | |
| 28 | +#define NEON_RESET_N BIT(15) | |
| 29 | +#define PWR_CTRL_STATUS_SHIFT 28 | |
| 30 | +#define PWR_CTRL_STATUS_MASK 0x3 | |
| 31 | +#define PWR_DOWN_SHIFT 30 | |
| 32 | +#define PWR_DOWN_MASK 0x3 | |
| 33 | + | |
| 34 | +/* CPU Power control register definitions */ | |
| 35 | +#define MEM_PWR_OK BIT(0) | |
| 36 | +#define MEM_PWR_ON BIT(1) | |
| 37 | +#define MEM_CLAMP_ON BIT(2) | |
| 38 | +#define MEM_PWR_OK_STATUS BIT(4) | |
| 39 | +#define MEM_PWR_ON_STATUS BIT(5) | |
| 40 | +#define MEM_PDA_SHIFT 8 | |
| 41 | +#define MEM_PDA_MASK 0xf | |
| 42 | +#define MEM_PDA_CPU_MASK 0x1 | |
| 43 | +#define MEM_PDA_NEON_MASK 0xf | |
| 44 | +#define CLAMP_ON BIT(15) | |
| 45 | +#define PWR_OK_SHIFT 16 | |
| 46 | +#define PWR_OK_MASK 0xf | |
| 47 | +#define PWR_ON_SHIFT 20 | |
| 48 | +#define PWR_CPU_MASK 0x03 | |
| 49 | +#define PWR_NEON_MASK 0x01 | |
| 50 | +#define PWR_ON_MASK 0xf | |
| 51 | +#define PWR_OK_STATUS_SHIFT 24 | |
| 52 | +#define PWR_OK_STATUS_MASK 0xf | |
| 53 | +#define PWR_ON_STATUS_SHIFT 28 | |
| 54 | +#define PWR_ON_STATUS_MASK 0xf | |
| 55 | + | |
| 56 | +#define ARM_CONTROL 0x30 | |
| 57 | +#define ARM_PWR_CONTROL_BASE 0x34 | |
| 58 | +#define ARM_PWR_CONTROL(x) (ARM_PWR_CONTROL_BASE + (x) * 0x4) | |
| 59 | +#define ARM_NEON_L2 0x3c | |
| 60 | + | |
| 61 | +/* Perform a value write, then spin until the value shifted by | |
| 62 | + * shift is seen, masked with mask and is different from cond. | |
| 63 | + */ | |
| 64 | +static int bpcm_wr_rd_mask(void __iomem *master, | |
| 65 | + unsigned int addr, u32 off, u32 *val, | |
| 66 | + u32 shift, u32 mask, u32 cond) | |
| 67 | +{ | |
| 68 | + int ret; | |
| 69 | + | |
| 70 | + ret = bpcm_wr(master, addr, off, *val); | |
| 71 | + if (ret) | |
| 72 | + return ret; | |
| 73 | + | |
| 74 | + do { | |
| 75 | + ret = bpcm_rd(master, addr, off, val); | |
| 76 | + if (ret) | |
| 77 | + return ret; | |
| 78 | + | |
| 79 | + cpu_relax(); | |
| 80 | + } while (((*val >> shift) & mask) != cond); | |
| 81 | + | |
| 82 | + return ret; | |
| 83 | +} | |
| 84 | + | |
| 85 | +/* Global lock to serialize accesses to the PMB registers while we | |
| 86 | + * are bringing up the secondary CPU | |
| 87 | + */ | |
| 88 | +static DEFINE_SPINLOCK(pmb_lock); | |
| 89 | + | |
| 90 | +static int bcm63xx_pmb_get_resources(struct device_node *dn, | |
| 91 | + void __iomem **base, | |
| 92 | + unsigned int *cpu, | |
| 93 | + unsigned int *addr) | |
| 94 | +{ | |
| 95 | + struct device_node *pmb_dn; | |
| 96 | + struct of_phandle_args args; | |
| 97 | + int ret; | |
| 98 | + | |
| 99 | + ret = of_property_read_u32(dn, "reg", cpu); | |
| 100 | + if (ret) { | |
| 101 | + pr_err("CPU is missing a reg node\n"); | |
| 102 | + return ret; | |
| 103 | + } | |
| 104 | + | |
| 105 | + ret = of_parse_phandle_with_args(dn, "resets", "#reset-cells", | |
| 106 | + 0, &args); | |
| 107 | + if (ret) { | |
| 108 | + pr_err("CPU is missing a resets phandle\n"); | |
| 109 | + return ret; | |
| 110 | + } | |
| 111 | + | |
| 112 | + pmb_dn = args.np; | |
| 113 | + if (args.args_count != 2) { | |
| 114 | + pr_err("reset-controller does not conform to reset-cells\n"); | |
| 115 | + return -EINVAL; | |
| 116 | + } | |
| 117 | + | |
| 118 | + *base = of_iomap(args.np, 0); | |
| 119 | + if (!*base) { | |
| 120 | + pr_err("failed remapping PMB register\n"); | |
| 121 | + return -ENOMEM; | |
| 122 | + } | |
| 123 | + | |
| 124 | + /* We do not need the number of zones */ | |
| 125 | + *addr = args.args[0]; | |
| 126 | + | |
| 127 | + return 0; | |
| 128 | +} | |
| 129 | + | |
| 130 | +int bcm63xx_pmb_power_on_cpu(struct device_node *dn) | |
| 131 | +{ | |
| 132 | + void __iomem *base; | |
| 133 | + unsigned int cpu, addr; | |
| 134 | + unsigned long flags; | |
| 135 | + u32 val, ctrl; | |
| 136 | + int ret; | |
| 137 | + | |
| 138 | + ret = bcm63xx_pmb_get_resources(dn, &base, &cpu, &addr); | |
| 139 | + if (ret) | |
| 140 | + return ret; | |
| 141 | + | |
| 142 | + /* We would not know how to enable a third and greater CPU */ | |
| 143 | + WARN_ON(cpu > 1); | |
| 144 | + | |
| 145 | + spin_lock_irqsave(&pmb_lock, flags); | |
| 146 | + | |
| 147 | + /* Check if the CPU is already on and save the ARM_CONTROL register | |
| 148 | + * value since we will use it later for CPU de-assert once done with | |
| 149 | + * the CPU-specific power sequence | |
| 150 | + */ | |
| 151 | + ret = bpcm_rd(base, addr, ARM_CONTROL, &ctrl); | |
| 152 | + if (ret) | |
| 153 | + goto out; | |
| 154 | + | |
| 155 | + if (ctrl & CPU_RESET_N(cpu)) { | |
| 156 | + pr_info("PMB: CPU%d is already powered on\n", cpu); | |
| 157 | + ret = 0; | |
| 158 | + goto out; | |
| 159 | + } | |
| 160 | + | |
| 161 | + /* Power on PLL */ | |
| 162 | + ret = bpcm_rd(base, addr, ARM_PWR_CONTROL(cpu), &val); | |
| 163 | + if (ret) | |
| 164 | + goto out; | |
| 165 | + | |
| 166 | + val |= (PWR_CPU_MASK << PWR_ON_SHIFT); | |
| 167 | + | |
| 168 | + ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val, | |
| 169 | + PWR_ON_STATUS_SHIFT, PWR_CPU_MASK, PWR_CPU_MASK); | |
| 170 | + if (ret) | |
| 171 | + goto out; | |
| 172 | + | |
| 173 | + val |= (PWR_CPU_MASK << PWR_OK_SHIFT); | |
| 174 | + | |
| 175 | + ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val, | |
| 176 | + PWR_OK_STATUS_SHIFT, PWR_CPU_MASK, PWR_CPU_MASK); | |
| 177 | + if (ret) | |
| 178 | + goto out; | |
| 179 | + | |
| 180 | + val &= ~CLAMP_ON; | |
| 181 | + | |
| 182 | + ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val); | |
| 183 | + if (ret) | |
| 184 | + goto out; | |
| 185 | + | |
| 186 | + /* Power on CPU<N> RAM */ | |
| 187 | + val &= ~(MEM_PDA_MASK << MEM_PDA_SHIFT); | |
| 188 | + | |
| 189 | + ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val); | |
| 190 | + if (ret) | |
| 191 | + goto out; | |
| 192 | + | |
| 193 | + val |= MEM_PWR_ON; | |
| 194 | + | |
| 195 | + ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val, | |
| 196 | + 0, MEM_PWR_ON_STATUS, MEM_PWR_ON_STATUS); | |
| 197 | + if (ret) | |
| 198 | + goto out; | |
| 199 | + | |
| 200 | + val |= MEM_PWR_OK; | |
| 201 | + | |
| 202 | + ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val, | |
| 203 | + 0, MEM_PWR_OK_STATUS, MEM_PWR_OK_STATUS); | |
| 204 | + if (ret) | |
| 205 | + goto out; | |
| 206 | + | |
| 207 | + val &= ~MEM_CLAMP_ON; | |
| 208 | + | |
| 209 | + ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val); | |
| 210 | + if (ret) | |
| 211 | + goto out; | |
| 212 | + | |
| 213 | + /* De-assert CPU reset */ | |
| 214 | + ctrl |= CPU_RESET_N(cpu); | |
| 215 | + | |
| 216 | + ret = bpcm_wr(base, addr, ARM_CONTROL, ctrl); | |
| 217 | +out: | |
| 218 | + spin_unlock_irqrestore(&pmb_lock, flags); | |
| 219 | + iounmap(base); | |
| 220 | + return ret; | |
| 221 | +} | |
| @@ -0,0 +1,169 @@ | ||
| 1 | +/* | |
| 2 | + * Broadcom BCM63138 DSL SoCs SMP support code | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015, Broadcom Corporation | |
| 5 | + * | |
| 6 | + * Licensed under the terms of the GPLv2 | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#include <linux/delay.h> | |
| 10 | +#include <linux/init.h> | |
| 11 | +#include <linux/smp.h> | |
| 12 | +#include <linux/io.h> | |
| 13 | +#include <linux/of.h> | |
| 14 | +#include <linux/of_address.h> | |
| 15 | + | |
| 16 | +#include <asm/cacheflush.h> | |
| 17 | +#include <asm/smp_scu.h> | |
| 18 | +#include <asm/smp_plat.h> | |
| 19 | +#include <asm/vfp.h> | |
| 20 | + | |
| 21 | +#include "bcm63xx_smp.h" | |
| 22 | + | |
| 23 | +/* Size of mapped Cortex A9 SCU address space */ | |
| 24 | +#define CORTEX_A9_SCU_SIZE 0x58 | |
| 25 | + | |
| 26 | +/* | |
| 27 | + * Enable the Cortex A9 Snoop Control Unit | |
| 28 | + * | |
| 29 | + * By the time this is called we already know there are multiple | |
| 30 | + * cores present. We assume we're running on a Cortex A9 processor, | |
| 31 | + * so any trouble getting the base address register or getting the | |
| 32 | + * SCU base is a problem. | |
| 33 | + * | |
| 34 | + * Return 0 if successful or an error code otherwise. | |
| 35 | + */ | |
| 36 | +static int __init scu_a9_enable(void) | |
| 37 | +{ | |
| 38 | + unsigned long config_base; | |
| 39 | + void __iomem *scu_base; | |
| 40 | + unsigned int i, ncores; | |
| 41 | + | |
| 42 | + if (!scu_a9_has_base()) { | |
| 43 | + pr_err("no configuration base address register!\n"); | |
| 44 | + return -ENXIO; | |
| 45 | + } | |
| 46 | + | |
| 47 | + /* Config base address register value is zero for uniprocessor */ | |
| 48 | + config_base = scu_a9_get_base(); | |
| 49 | + if (!config_base) { | |
| 50 | + pr_err("hardware reports only one core\n"); | |
| 51 | + return -ENOENT; | |
| 52 | + } | |
| 53 | + | |
| 54 | + scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE); | |
| 55 | + if (!scu_base) { | |
| 56 | + pr_err("failed to remap config base (%lu/%u) for SCU\n", | |
| 57 | + config_base, CORTEX_A9_SCU_SIZE); | |
| 58 | + return -ENOMEM; | |
| 59 | + } | |
| 60 | + | |
| 61 | + scu_enable(scu_base); | |
| 62 | + | |
| 63 | + ncores = scu_base ? scu_get_core_count(scu_base) : 1; | |
| 64 | + | |
| 65 | + if (ncores > nr_cpu_ids) { | |
| 66 | + pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", | |
| 67 | + ncores, nr_cpu_ids); | |
| 68 | + ncores = nr_cpu_ids; | |
| 69 | + } | |
| 70 | + | |
| 71 | + /* The BCM63138 SoC has two Cortex-A9 CPUs, CPU0 features a complete | |
| 72 | + * and fully functional VFP unit that can be used, but CPU1 does not. | |
| 73 | + * Since we will not be able to trap kernel-mode NEON to force | |
| 74 | + * migration to CPU0, just do not advertise VFP support at all. | |
| 75 | + * | |
| 76 | + * This will make vfp_init bail out and do not attempt to use VFP at | |
| 77 | + * all, for kernel-mode NEON, we do not want to introduce any | |
| 78 | + * conditionals in hot-paths, so we just restrict the system to UP. | |
| 79 | + */ | |
| 80 | +#ifdef CONFIG_VFP | |
| 81 | + if (ncores > 1) { | |
| 82 | + pr_warn("SMP: secondary CPUs lack VFP unit, disabling VFP\n"); | |
| 83 | + vfp_disable(); | |
| 84 | + | |
| 85 | +#ifdef CONFIG_KERNEL_MODE_NEON | |
| 86 | + WARN(1, "SMP: kernel-mode NEON enabled, restricting to UP\n"); | |
| 87 | + ncores = 1; | |
| 88 | +#endif | |
| 89 | + } | |
| 90 | +#endif | |
| 91 | + | |
| 92 | + for (i = 0; i < ncores; i++) | |
| 93 | + set_cpu_possible(i, true); | |
| 94 | + | |
| 95 | + iounmap(scu_base); /* That's the last we'll need of this */ | |
| 96 | + | |
| 97 | + return 0; | |
| 98 | +} | |
| 99 | + | |
| 100 | +static const struct of_device_id bcm63138_bootlut_ids[] = { | |
| 101 | + { .compatible = "brcm,bcm63138-bootlut", }, | |
| 102 | + { /* sentinel */ }, | |
| 103 | +}; | |
| 104 | + | |
| 105 | +#define BOOTLUT_RESET_VECT 0x20 | |
| 106 | + | |
| 107 | +static int bcm63138_smp_boot_secondary(unsigned int cpu, | |
| 108 | + struct task_struct *idle) | |
| 109 | +{ | |
| 110 | + void __iomem *bootlut_base; | |
| 111 | + struct device_node *dn; | |
| 112 | + int ret = 0; | |
| 113 | + u32 val; | |
| 114 | + | |
| 115 | + dn = of_find_matching_node(NULL, bcm63138_bootlut_ids); | |
| 116 | + if (!dn) { | |
| 117 | + pr_err("SMP: unable to find bcm63138 boot LUT node\n"); | |
| 118 | + return -ENODEV; | |
| 119 | + } | |
| 120 | + | |
| 121 | + bootlut_base = of_iomap(dn, 0); | |
| 122 | + of_node_put(dn); | |
| 123 | + | |
| 124 | + if (!bootlut_base) { | |
| 125 | + pr_err("SMP: unable to remap boot LUT base register\n"); | |
| 126 | + return -ENOMEM; | |
| 127 | + } | |
| 128 | + | |
| 129 | + /* Locate the secondary CPU node */ | |
| 130 | + dn = of_get_cpu_node(cpu_logical_map(cpu), NULL); | |
| 131 | + if (!dn) { | |
| 132 | + pr_err("SMP: failed to locate secondary CPU%d node\n", cpu); | |
| 133 | + ret = -ENODEV; | |
| 134 | + goto out; | |
| 135 | + } | |
| 136 | + | |
| 137 | + /* Write the secondary init routine to the BootLUT reset vector */ | |
| 138 | + val = virt_to_phys(bcm63138_secondary_startup); | |
| 139 | + writel_relaxed(val, bootlut_base + BOOTLUT_RESET_VECT); | |
| 140 | + | |
| 141 | + /* Power up the core, will jump straight to its reset vector when we | |
| 142 | + * return | |
| 143 | + */ | |
| 144 | + ret = bcm63xx_pmb_power_on_cpu(dn); | |
| 145 | + if (ret) | |
| 146 | + goto out; | |
| 147 | +out: | |
| 148 | + iounmap(bootlut_base); | |
| 149 | + | |
| 150 | + return ret; | |
| 151 | +} | |
| 152 | + | |
| 153 | +static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus) | |
| 154 | +{ | |
| 155 | + int ret; | |
| 156 | + | |
| 157 | + ret = scu_a9_enable(); | |
| 158 | + if (ret) { | |
| 159 | + pr_warn("SMP: Cortex-A9 SCU setup failed\n"); | |
| 160 | + return; | |
| 161 | + } | |
| 162 | +} | |
| 163 | + | |
| 164 | +struct smp_operations bcm63138_smp_ops __initdata = { | |
| 165 | + .smp_prepare_cpus = bcm63138_smp_prepare_cpus, | |
| 166 | + .smp_boot_secondary = bcm63138_smp_boot_secondary, | |
| 167 | +}; | |
| 168 | + | |
| 169 | +CPU_METHOD_OF_DECLARE(bcm63138_smp, "brcm,bcm63138", &bcm63138_smp_ops); | |
| @@ -0,0 +1,9 @@ | ||
| 1 | +#ifndef __BCM63XX_SMP_H | |
| 2 | +#define __BCM63XX_SMP_H | |
| 3 | + | |
| 4 | +struct device_node; | |
| 5 | + | |
| 6 | +extern void bcm63138_secondary_startup(void); | |
| 7 | +extern int bcm63xx_pmb_power_on_cpu(struct device_node *dn); | |
| 8 | + | |
| 9 | +#endif /* __BCM63XX_SMP_H */ | |
| @@ -18,15 +18,16 @@ static bool first_fault = true; · 17 unmodified lines | ||
| 18 | 18 | static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr, |
| 19 | 19 | struct pt_regs *regs) |
| 20 | 20 | { |
| 21 | − if (fsr == 0x1c06 && first_fault) { | |
| 21 | + if ((fsr == 0x1406 || fsr == 0x1c06) && first_fault) { | |
| 22 | 22 | first_fault = false; |
| 23 | 23 | |
| 24 | 24 | /* |
| 25 | − * These faults with code 0x1c06 happens for no good reason, | |
| 26 | − * possibly left over from the CFE boot loader. | |
| 25 | + * These faults with codes 0x1406 (BCM4709) or 0x1c06 happens | |
| 26 | + * for no good reason, possibly left over from the CFE boot | |
| 27 | + * loader. | |
| 27 | 28 | */ |
| 28 | 29 | pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n", |
| 29 | − addr, fsr); | |
| 30 | + addr, fsr); | |
| 30 | 31 | |
| 31 | 32 | /* Returning non-zero causes fault display and panic */ |
| 32 | 33 | return 0; |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | ||
| 12 | 12 | * GNU General Public License for more details. |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | −#include <linux/delay.h> | |
| 16 | 15 | #include <linux/init.h> |
| 17 | 16 | #include <linux/irqchip.h> |
| 18 | 17 | #include <linux/of_address.h> |
| @@ -22,97 +21,10 @@ · 3 unmodified lines | ||
| 22 | 21 | #include <asm/mach/arch.h> |
| 23 | 22 | #include <asm/mach/map.h> |
| 24 | 23 | |
| 25 | −#define PM_RSTC 0x1c | |
| 26 | −#define PM_RSTS 0x20 | |
| 27 | −#define PM_WDOG 0x24 | |
| 28 | − | |
| 29 | −#define PM_PASSWORD 0x5a000000 | |
| 30 | −#define PM_RSTC_WRCFG_MASK 0x00000030 | |
| 31 | −#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 | |
| 32 | −#define PM_RSTS_HADWRH_SET 0x00000040 | |
| 33 | − | |
| 34 | −#define BCM2835_PERIPH_PHYS 0x20000000 | |
| 35 | −#define BCM2835_PERIPH_VIRT 0xf0000000 | |
| 36 | −#define BCM2835_PERIPH_SIZE SZ_16M | |
| 37 | − | |
| 38 | −static void __iomem *wdt_regs; | |
| 39 | − | |
| 40 | −/* | |
| 41 | − * The machine restart method can be called from an atomic context so we won't | |
| 42 | − * be able to ioremap the regs then. | |
| 43 | − */ | |
| 44 | −static void bcm2835_setup_restart(void) | |
| 45 | −{ | |
| 46 | − struct device_node *np = of_find_compatible_node(NULL, NULL, | |
| 47 | − "brcm,bcm2835-pm-wdt"); | |
| 48 | − if (WARN(!np, "unable to setup watchdog restart")) | |
| 49 | − return; | |
| 50 | − | |
| 51 | − wdt_regs = of_iomap(np, 0); | |
| 52 | − WARN(!wdt_regs, "failed to remap watchdog regs"); | |
| 53 | −} | |
| 54 | − | |
| 55 | −static void bcm2835_restart(enum reboot_mode mode, const char *cmd) | |
| 56 | −{ | |
| 57 | − u32 val; | |
| 58 | − | |
| 59 | − if (!wdt_regs) | |
| 60 | − return; | |
| 61 | − | |
| 62 | − /* use a timeout of 10 ticks (~150us) */ | |
| 63 | − writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG); | |
| 64 | − val = readl_relaxed(wdt_regs + PM_RSTC); | |
| 65 | − val &= ~PM_RSTC_WRCFG_MASK; | |
| 66 | − val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET; | |
| 67 | − writel_relaxed(val, wdt_regs + PM_RSTC); | |
| 68 | − | |
| 69 | − /* No sleeping, possibly atomic. */ | |
| 70 | − mdelay(1); | |
| 71 | −} | |
| 72 | − | |
| 73 | −/* | |
| 74 | − * We can't really power off, but if we do the normal reset scheme, and | |
| 75 | − * indicate to bootcode.bin not to reboot, then most of the chip will be | |
| 76 | − * powered off. | |
| 77 | − */ | |
| 78 | −static void bcm2835_power_off(void) | |
| 79 | −{ | |
| 80 | − u32 val; | |
| 81 | − | |
| 82 | − /* | |
| 83 | − * We set the watchdog hard reset bit here to distinguish this reset | |
| 84 | − * from the normal (full) reset. bootcode.bin will not reboot after a | |
| 85 | − * hard reset. | |
| 86 | − */ | |
| 87 | − val = readl_relaxed(wdt_regs + PM_RSTS); | |
| 88 | − val &= ~PM_RSTC_WRCFG_MASK; | |
| 89 | − val |= PM_PASSWORD | PM_RSTS_HADWRH_SET; | |
| 90 | − writel_relaxed(val, wdt_regs + PM_RSTS); | |
| 91 | − | |
| 92 | − /* Continue with normal reset mechanism */ | |
| 93 | − bcm2835_restart(REBOOT_HARD, ""); | |
| 94 | −} | |
| 95 | − | |
| 96 | −static struct map_desc io_map __initdata = { | |
| 97 | − .virtual = BCM2835_PERIPH_VIRT, | |
| 98 | − .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS), | |
| 99 | − .length = BCM2835_PERIPH_SIZE, | |
| 100 | − .type = MT_DEVICE | |
| 101 | −}; | |
| 102 | − | |
| 103 | −static void __init bcm2835_map_io(void) | |
| 104 | −{ | |
| 105 | − iotable_init(&io_map, 1); | |
| 106 | −} | |
| 107 | − | |
| 108 | 24 | static void __init bcm2835_init(void) |
| 109 | 25 | { |
| 110 | 26 | int ret; |
| 111 | 27 | |
| 112 | − bcm2835_setup_restart(); | |
| 113 | − if (wdt_regs) | |
| 114 | − pm_power_off = bcm2835_power_off; | |
| 115 | − | |
| 116 | 28 | bcm2835_init_clocks(); |
| 117 | 29 | |
| 118 | 30 | ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, |
| @@ -129,9 +41,6 @@ static const char * const bcm2835_compat[] = { · 10 unmodified lines | ||
| 129 | 41 | }; |
| 130 | 42 | |
| 131 | 43 | DT_MACHINE_START(BCM2835, "BCM2835") |
| 132 | − .map_io = bcm2835_map_io, | |
| 133 | − .init_irq = irqchip_init, | |
| 134 | 44 | .init_machine = bcm2835_init, |
| 135 | − .restart = bcm2835_restart, | |
| 136 | 45 | .dt_compat = bcm2835_compat |
| 137 | 46 | MACHINE_END |
| @@ -20,9 +20,14 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/platform_device.h> |
| 21 | 21 | #include <linux/i2c.h> |
| 22 | 22 | #include <linux/i2c-gpio.h> |
| 23 | +#include <linux/mmc/host.h> | |
| 24 | +#include <linux/spi/spi.h> | |
| 25 | +#include <linux/spi/mmc_spi.h> | |
| 26 | +#include <linux/platform_data/video-ep93xx.h> | |
| 27 | +#include <linux/platform_data/spi-ep93xx.h> | |
| 28 | +#include <linux/gpio.h> | |
| 23 | 29 | |
| 24 | 30 | #include <mach/hardware.h> |
| 25 | −#include <linux/platform_data/video-ep93xx.h> | |
| 26 | 31 | #include <mach/gpio-ep93xx.h> |
| 27 | 32 | |
| 28 | 33 | #include <asm/mach-types.h> |
| @@ -40,6 +45,132 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = { · 11 unmodified lines | ||
| 40 | 45 | .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING, |
| 41 | 46 | }; |
| 42 | 47 | |
| 48 | +/* | |
| 49 | + * GPIO lines used for MMC card detection. | |
| 50 | + */ | |
| 51 | +#define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 | |
| 52 | + | |
| 53 | +/* | |
| 54 | + * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes | |
| 55 | + * low between multi-message command blocks. From v1.4, it uses a GPIO instead. | |
| 56 | + * v1.3 parts will still work, since the signal on SFRMOUT is automatic. | |
| 57 | + */ | |
| 58 | +#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1 | |
| 59 | + | |
| 60 | +/* | |
| 61 | + * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal, | |
| 62 | + * you can leave these empty and pass NULL as .controller_data. | |
| 63 | + */ | |
| 64 | + | |
| 65 | +static int simone_mmc_spi_setup(struct spi_device *spi) | |
| 66 | +{ | |
| 67 | + unsigned int gpio = MMC_CHIP_SELECT_GPIO; | |
| 68 | + int err; | |
| 69 | + | |
| 70 | + err = gpio_request(gpio, spi->modalias); | |
| 71 | + if (err) | |
| 72 | + return err; | |
| 73 | + | |
| 74 | + err = gpio_direction_output(gpio, 1); | |
| 75 | + if (err) { | |
| 76 | + gpio_free(gpio); | |
| 77 | + return err; | |
| 78 | + } | |
| 79 | + | |
| 80 | + return 0; | |
| 81 | +} | |
| 82 | + | |
| 83 | +static void simone_mmc_spi_cleanup(struct spi_device *spi) | |
| 84 | +{ | |
| 85 | + unsigned int gpio = MMC_CHIP_SELECT_GPIO; | |
| 86 | + | |
| 87 | + gpio_set_value(gpio, 1); | |
| 88 | + gpio_direction_input(gpio); | |
| 89 | + gpio_free(gpio); | |
| 90 | +} | |
| 91 | + | |
| 92 | +static void simone_mmc_spi_cs_control(struct spi_device *spi, int value) | |
| 93 | +{ | |
| 94 | + gpio_set_value(MMC_CHIP_SELECT_GPIO, value); | |
| 95 | +} | |
| 96 | + | |
| 97 | +static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = { | |
| 98 | + .setup = simone_mmc_spi_setup, | |
| 99 | + .cleanup = simone_mmc_spi_cleanup, | |
| 100 | + .cs_control = simone_mmc_spi_cs_control, | |
| 101 | +}; | |
| 102 | + | |
| 103 | +/* | |
| 104 | + * MMC card detection GPIO setup. | |
| 105 | + */ | |
| 106 | + | |
| 107 | +static int simone_mmc_spi_init(struct device *dev, | |
| 108 | + irqreturn_t (*irq_handler)(int, void *), void *mmc) | |
| 109 | +{ | |
| 110 | + unsigned int gpio = MMC_CARD_DETECT_GPIO; | |
| 111 | + int irq, err; | |
| 112 | + | |
| 113 | + err = gpio_request(gpio, dev_name(dev)); | |
| 114 | + if (err) | |
| 115 | + return err; | |
| 116 | + | |
| 117 | + err = gpio_direction_input(gpio); | |
| 118 | + if (err) | |
| 119 | + goto fail; | |
| 120 | + | |
| 121 | + irq = gpio_to_irq(gpio); | |
| 122 | + if (irq < 0) | |
| 123 | + goto fail; | |
| 124 | + | |
| 125 | + err = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING, | |
| 126 | + "MMC card detect", mmc); | |
| 127 | + if (err) | |
| 128 | + goto fail; | |
| 129 | + | |
| 130 | + printk(KERN_INFO "%s: using irq %d for MMC card detection\n", | |
| 131 | + dev_name(dev), irq); | |
| 132 | + | |
| 133 | + return 0; | |
| 134 | +fail: | |
| 135 | + gpio_free(gpio); | |
| 136 | + return err; | |
| 137 | +} | |
| 138 | + | |
| 139 | +static void simone_mmc_spi_exit(struct device *dev, void *mmc) | |
| 140 | +{ | |
| 141 | + unsigned int gpio = MMC_CARD_DETECT_GPIO; | |
| 142 | + | |
| 143 | + free_irq(gpio_to_irq(gpio), mmc); | |
| 144 | + gpio_free(gpio); | |
| 145 | +} | |
| 146 | + | |
| 147 | +static struct mmc_spi_platform_data simone_mmc_spi_data = { | |
| 148 | + .init = simone_mmc_spi_init, | |
| 149 | + .exit = simone_mmc_spi_exit, | |
| 150 | + .detect_delay = 500, | |
| 151 | + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | |
| 152 | +}; | |
| 153 | + | |
| 154 | +static struct spi_board_info simone_spi_devices[] __initdata = { | |
| 155 | + { | |
| 156 | + .modalias = "mmc_spi", | |
| 157 | + .controller_data = &simone_mmc_spi_ops, | |
| 158 | + .platform_data = &simone_mmc_spi_data, | |
| 159 | + /* | |
| 160 | + * We use 10 MHz even though the maximum is 3.7 MHz. The driver | |
| 161 | + * will limit it automatically to max. frequency. | |
| 162 | + */ | |
| 163 | + .max_speed_hz = 10 * 1000 * 1000, | |
| 164 | + .bus_num = 0, | |
| 165 | + .chip_select = 0, | |
| 166 | + .mode = SPI_MODE_3, | |
| 167 | + }, | |
| 168 | +}; | |
| 169 | + | |
| 170 | +static struct ep93xx_spi_info simone_spi_info __initdata = { | |
| 171 | + .num_chipselect = ARRAY_SIZE(simone_spi_devices), | |
| 172 | +}; | |
| 173 | + | |
| 43 | 174 | static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = { |
| 44 | 175 | .sda_pin = EP93XX_GPIO_LINE_EEDAT, |
| 45 | 176 | .sda_is_open_drain = 0, |
| @@ -74,6 +205,8 @@ static void __init simone_init_machine(void) · 28 unmodified lines | ||
| 74 | 205 | ep93xx_register_fb(&simone_fb_info); |
| 75 | 206 | ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info, |
| 76 | 207 | ARRAY_SIZE(simone_i2c_board_info)); |
| 208 | + ep93xx_register_spi(&simone_spi_info, simone_spi_devices, | |
| 209 | + ARRAY_SIZE(simone_spi_devices)); | |
| 77 | 210 | simone_register_audio(); |
| 78 | 211 | } |
| 79 | 212 | |
| @@ -163,7 +163,9 @@ extern void exynos_set_delayed_reset_assertion(bool enable); · 162 unmodified lines | ||
| 163 | 163 | |
| 164 | 164 | extern void s5p_init_cpu(void __iomem *cpuid_addr); |
| 165 | 165 | extern unsigned int samsung_rev(void); |
| 166 | −extern void __iomem *cpu_boot_reg_base(void); | |
| 166 | +extern void exynos_core_restart(u32 core_id); | |
| 167 | +extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr); | |
| 168 | +extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr); | |
| 167 | 169 | |
| 168 | 170 | static inline void pmu_raw_writel(u32 val, u32 offset) |
| 169 | 171 | { |
| @@ -234,7 +234,8 @@ static void __init exynos_dt_machine_init(void) · 233 unmodified lines | ||
| 234 | 234 | exynos_sysram_init(); |
| 235 | 235 | |
| 236 | 236 | #if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE) |
| 237 | − if (of_machine_is_compatible("samsung,exynos4210")) | |
| 237 | + if (of_machine_is_compatible("samsung,exynos4210") || | |
| 238 | + of_machine_is_compatible("samsung,exynos3250")) | |
| 238 | 239 | exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data; |
| 239 | 240 | #endif |
| 240 | 241 | if (of_machine_is_compatible("samsung,exynos4210") || |
| @@ -49,6 +49,7 @@ static int exynos_do_idle(unsigned long mode) · 48 unmodified lines | ||
| 49 | 49 | sysram_ns_base_addr + 0x24); |
| 50 | 50 | __raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20); |
| 51 | 51 | if (soc_is_exynos3250()) { |
| 52 | + flush_cache_all(); | |
| 52 | 53 | exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE, |
| 53 | 54 | SMC_POWERSTATE_IDLE, 0); |
| 54 | 55 | exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER, |
| @@ -104,6 +105,22 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr) · 49 unmodified lines | ||
| 104 | 105 | return 0; |
| 105 | 106 | } |
| 106 | 107 | |
| 108 | +static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr) | |
| 109 | +{ | |
| 110 | + void __iomem *boot_reg; | |
| 111 | + | |
| 112 | + if (!sysram_ns_base_addr) | |
| 113 | + return -ENODEV; | |
| 114 | + | |
| 115 | + boot_reg = sysram_ns_base_addr + 0x1c; | |
| 116 | + | |
| 117 | + if (soc_is_exynos4412()) | |
| 118 | + boot_reg += 4 * cpu; | |
| 119 | + | |
| 120 | + *boot_addr = __raw_readl(boot_reg); | |
| 121 | + return 0; | |
| 122 | +} | |
| 123 | + | |
| 107 | 124 | static int exynos_cpu_suspend(unsigned long arg) |
| 108 | 125 | { |
| 109 | 126 | flush_cache_all(); |
| @@ -138,6 +155,7 @@ static int exynos_resume(void) · 28 unmodified lines | ||
| 138 | 155 | static const struct firmware_ops exynos_firmware_ops = { |
| 139 | 156 | .do_idle = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL, |
| 140 | 157 | .set_cpu_boot_addr = exynos_set_cpu_boot_addr, |
| 158 | + .get_cpu_boot_addr = exynos_get_cpu_boot_addr, | |
| 141 | 159 | .cpu_boot = exynos_cpu_boot, |
| 142 | 160 | .suspend = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL, |
| 143 | 161 | .resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL, |
| @@ -169,7 +169,7 @@ int exynos_cluster_power_state(int cluster) · 168 unmodified lines | ||
| 169 | 169 | S5P_CORE_LOCAL_PWR_EN); |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | −void __iomem *cpu_boot_reg_base(void) | |
| 172 | +static void __iomem *cpu_boot_reg_base(void) | |
| 173 | 173 | { |
| 174 | 174 | if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1) |
| 175 | 175 | return pmu_base_addr + S5P_INFORM5; |
| @@ -195,7 +195,7 @@ static inline void __iomem *cpu_boot_reg(int cpu) · 19 unmodified lines | ||
| 195 | 195 | * |
| 196 | 196 | * Currently this is needed only when booting secondary CPU on Exynos3250. |
| 197 | 197 | */ |
| 198 | −static void exynos_core_restart(u32 core_id) | |
| 198 | +void exynos_core_restart(u32 core_id) | |
| 199 | 199 | { |
| 200 | 200 | u32 val; |
| 201 | 201 | |
| @@ -210,7 +210,6 @@ static void exynos_core_restart(u32 core_id) · 8 unmodified lines | ||
| 210 | 210 | val |= S5P_CORE_WAKEUP_FROM_LOCAL_CFG; |
| 211 | 211 | pmu_raw_writel(val, EXYNOS_ARM_CORE_STATUS(core_id)); |
| 212 | 212 | |
| 213 | − pr_info("CPU%u: Software reset\n", core_id); | |
| 214 | 213 | pmu_raw_writel(EXYNOS_CORE_PO_RESET(core_id), EXYNOS_SWRESET); |
| 215 | 214 | } |
| 216 | 215 | |
| @@ -248,6 +247,56 @@ static void exynos_secondary_init(unsigned int cpu) · 31 unmodified lines | ||
| 248 | 247 | spin_unlock(&boot_lock); |
| 249 | 248 | } |
| 250 | 249 | |
| 250 | +int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr) | |
| 251 | +{ | |
| 252 | + int ret; | |
| 253 | + | |
| 254 | + /* | |
| 255 | + * Try to set boot address using firmware first | |
| 256 | + * and fall back to boot register if it fails. | |
| 257 | + */ | |
| 258 | + ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr); | |
| 259 | + if (ret && ret != -ENOSYS) | |
| 260 | + goto fail; | |
| 261 | + if (ret == -ENOSYS) { | |
| 262 | + void __iomem *boot_reg = cpu_boot_reg(core_id); | |
| 263 | + | |
| 264 | + if (IS_ERR(boot_reg)) { | |
| 265 | + ret = PTR_ERR(boot_reg); | |
| 266 | + goto fail; | |
| 267 | + } | |
| 268 | + __raw_writel(boot_addr, boot_reg); | |
| 269 | + ret = 0; | |
| 270 | + } | |
| 271 | +fail: | |
| 272 | + return ret; | |
| 273 | +} | |
| 274 | + | |
| 275 | +int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr) | |
| 276 | +{ | |
| 277 | + int ret; | |
| 278 | + | |
| 279 | + /* | |
| 280 | + * Try to get boot address using firmware first | |
| 281 | + * and fall back to boot register if it fails. | |
| 282 | + */ | |
| 283 | + ret = call_firmware_op(get_cpu_boot_addr, core_id, boot_addr); | |
| 284 | + if (ret && ret != -ENOSYS) | |
| 285 | + goto fail; | |
| 286 | + if (ret == -ENOSYS) { | |
| 287 | + void __iomem *boot_reg = cpu_boot_reg(core_id); | |
| 288 | + | |
| 289 | + if (IS_ERR(boot_reg)) { | |
| 290 | + ret = PTR_ERR(boot_reg); | |
| 291 | + goto fail; | |
| 292 | + } | |
| 293 | + *boot_addr = __raw_readl(boot_reg); | |
| 294 | + ret = 0; | |
| 295 | + } | |
| 296 | +fail: | |
| 297 | + return ret; | |
| 298 | +} | |
| 299 | + | |
| 251 | 300 | static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) |
| 252 | 301 | { |
| 253 | 302 | unsigned long timeout; |
| @@ -307,22 +356,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) · 53 unmodified lines | ||
| 307 | 356 | |
| 308 | 357 | boot_addr = virt_to_phys(exynos4_secondary_startup); |
| 309 | 358 | |
| 310 | − /* | |
| 311 | − * Try to set boot address using firmware first | |
| 312 | − * and fall back to boot register if it fails. | |
| 313 | − */ | |
| 314 | − ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr); | |
| 315 | − if (ret && ret != -ENOSYS) | |
| 359 | + ret = exynos_set_boot_addr(core_id, boot_addr); | |
| 360 | + if (ret) | |
| 316 | 361 | goto fail; |
| 317 | − if (ret == -ENOSYS) { | |
| 318 | − void __iomem *boot_reg = cpu_boot_reg(core_id); | |
| 319 | − | |
| 320 | − if (IS_ERR(boot_reg)) { | |
| 321 | − ret = PTR_ERR(boot_reg); | |
| 322 | − goto fail; | |
| 323 | − } | |
| 324 | − __raw_writel(boot_addr, boot_reg); | |
| 325 | − } | |
| 326 | 362 | |
| 327 | 363 | call_firmware_op(cpu_boot, core_id); |
| 328 | 364 | |
| @@ -337,6 +373,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) · 8 unmodified lines | ||
| 337 | 373 | udelay(10); |
| 338 | 374 | } |
| 339 | 375 | |
| 376 | + if (pen_release != -1) | |
| 377 | + ret = -ETIMEDOUT; | |
| 378 | + | |
| 340 | 379 | /* |
| 341 | 380 | * now the secondary core is starting up let it run its |
| 342 | 381 | * calibrations, then wait for it to finish |
| @@ -407,16 +446,9 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) · 64 unmodified lines | ||
| 407 | 446 | core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); |
| 408 | 447 | boot_addr = virt_to_phys(exynos4_secondary_startup); |
| 409 | 448 | |
| 410 | − ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr); | |
| 411 | − if (ret && ret != -ENOSYS) | |
| 449 | + ret = exynos_set_boot_addr(core_id, boot_addr); | |
| 450 | + if (ret) | |
| 412 | 451 | break; |
| 413 | − if (ret == -ENOSYS) { | |
| 414 | − void __iomem *boot_reg = cpu_boot_reg(core_id); | |
| 415 | − | |
| 416 | − if (IS_ERR(boot_reg)) | |
| 417 | − break; | |
| 418 | − __raw_writel(boot_addr, boot_reg); | |
| 419 | − } | |
| 420 | 452 | } |
| 421 | 453 | } |
| 422 | 454 | |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <asm/firmware.h> |
| 23 | 23 | #include <asm/smp_scu.h> |
| 24 | 24 | #include <asm/suspend.h> |
| 25 | +#include <asm/cacheflush.h> | |
| 25 | 26 | |
| 26 | 27 | #include <mach/map.h> |
| 27 | 28 | |
| @@ -209,6 +210,8 @@ static int exynos_cpu0_enter_aftr(void) · 181 unmodified lines | ||
| 209 | 210 | * sequence, let's wait for one of these to happen |
| 210 | 211 | */ |
| 211 | 212 | while (exynos_cpu_power_state(1)) { |
| 213 | + unsigned long boot_addr; | |
| 214 | + | |
| 212 | 215 | /* |
| 213 | 216 | * The other cpu may skip idle and boot back |
| 214 | 217 | * up again |
| @@ -221,7 +224,11 @@ static int exynos_cpu0_enter_aftr(void) · 6 unmodified lines | ||
| 221 | 224 | * boot back up again, getting stuck in the |
| 222 | 225 | * boot rom code |
| 223 | 226 | */ |
| 224 | − if (__raw_readl(cpu_boot_reg_base()) == 0) | |
| 227 | + ret = exynos_get_boot_addr(1, &boot_addr); | |
| 228 | + if (ret) | |
| 229 | + goto fail; | |
| 230 | + ret = -1; | |
| 231 | + if (boot_addr == 0) | |
| 225 | 232 | goto abort; |
| 226 | 233 | |
| 227 | 234 | cpu_relax(); |
| @@ -233,11 +240,14 @@ static int exynos_cpu0_enter_aftr(void) · 5 unmodified lines | ||
| 233 | 240 | |
| 234 | 241 | abort: |
| 235 | 242 | if (cpu_online(1)) { |
| 243 | + unsigned long boot_addr = virt_to_phys(exynos_cpu_resume); | |
| 244 | + | |
| 236 | 245 | /* |
| 237 | 246 | * Set the boot vector to something non-zero |
| 238 | 247 | */ |
| 239 | − __raw_writel(virt_to_phys(exynos_cpu_resume), | |
| 240 | − cpu_boot_reg_base()); | |
| 248 | + ret = exynos_set_boot_addr(1, boot_addr); | |
| 249 | + if (ret) | |
| 250 | + goto fail; | |
| 241 | 251 | dsb(); |
| 242 | 252 | |
| 243 | 253 | /* |
| @@ -247,22 +257,42 @@ abort: · 3 unmodified lines | ||
| 247 | 257 | while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN) |
| 248 | 258 | cpu_relax(); |
| 249 | 259 | |
| 260 | + if (soc_is_exynos3250()) { | |
| 261 | + while (!pmu_raw_readl(S5P_PMU_SPARE2) && | |
| 262 | + !atomic_read(&cpu1_wakeup)) | |
| 263 | + cpu_relax(); | |
| 264 | + | |
| 265 | + if (!atomic_read(&cpu1_wakeup)) | |
| 266 | + exynos_core_restart(1); | |
| 267 | + } | |
| 268 | + | |
| 250 | 269 | while (!atomic_read(&cpu1_wakeup)) { |
| 270 | + smp_rmb(); | |
| 271 | + | |
| 251 | 272 | /* |
| 252 | 273 | * Poke cpu1 out of the boot rom |
| 253 | 274 | */ |
| 254 | − __raw_writel(virt_to_phys(exynos_cpu_resume), | |
| 255 | − cpu_boot_reg_base()); | |
| 256 | 275 | |
| 257 | − arch_send_wakeup_ipi_mask(cpumask_of(1)); | |
| 276 | + ret = exynos_set_boot_addr(1, boot_addr); | |
| 277 | + if (ret) | |
| 278 | + goto fail; | |
| 279 | + | |
| 280 | + call_firmware_op(cpu_boot, 1); | |
| 281 | + | |
| 282 | + if (soc_is_exynos3250()) | |
| 283 | + dsb_sev(); | |
| 284 | + else | |
| 285 | + arch_send_wakeup_ipi_mask(cpumask_of(1)); | |
| 258 | 286 | } |
| 259 | 287 | } |
| 260 | − | |
| 288 | +fail: | |
| 261 | 289 | return ret; |
| 262 | 290 | } |
| 263 | 291 | |
| 264 | 292 | static int exynos_wfi_finisher(unsigned long flags) |
| 265 | 293 | { |
| 294 | + if (soc_is_exynos3250()) | |
| 295 | + flush_cache_all(); | |
| 266 | 296 | cpu_do_idle(); |
| 267 | 297 | |
| 268 | 298 | return -1; |
| @@ -283,6 +313,9 @@ static int exynos_cpu1_powerdown(void) · 14 unmodified lines | ||
| 283 | 313 | */ |
| 284 | 314 | exynos_cpu_power_down(1); |
| 285 | 315 | |
| 316 | + if (soc_is_exynos3250()) | |
| 317 | + pmu_raw_writel(0, S5P_PMU_SPARE2); | |
| 318 | + | |
| 286 | 319 | ret = cpu_suspend(0, exynos_wfi_finisher); |
| 287 | 320 | |
| 288 | 321 | cpu_pm_exit(); |
| @@ -299,7 +332,9 @@ cpu1_aborted: · 10 unmodified lines | ||
| 299 | 332 | |
| 300 | 333 | static void exynos_pre_enter_aftr(void) |
| 301 | 334 | { |
| 302 | − __raw_writel(virt_to_phys(exynos_cpu_resume), cpu_boot_reg_base()); | |
| 335 | + unsigned long boot_addr = virt_to_phys(exynos_cpu_resume); | |
| 336 | + | |
| 337 | + (void)exynos_set_boot_addr(1, boot_addr); | |
| 303 | 338 | } |
| 304 | 339 | |
| 305 | 340 | static void exynos_post_enter_aftr(void) |
| @@ -62,6 +62,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) · 61 unmodified lines | ||
| 62 | 62 | for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { |
| 63 | 63 | if (IS_ERR(pd->clk[i])) |
| 64 | 64 | break; |
| 65 | + pd->pclk[i] = clk_get_parent(pd->clk[i]); | |
| 65 | 66 | if (clk_set_parent(pd->clk[i], pd->oscclk)) |
| 66 | 67 | pr_err("%s: error setting oscclk as parent to clock %d\n", |
| 67 | 68 | pd->name, i); |
| @@ -90,6 +91,9 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) · 22 unmodified lines | ||
| 90 | 91 | for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { |
| 91 | 92 | if (IS_ERR(pd->clk[i])) |
| 92 | 93 | break; |
| 94 | + | |
| 95 | + if (IS_ERR(pd->clk[i])) | |
| 96 | + continue; /* Skip on first power up */ | |
| 93 | 97 | if (clk_set_parent(pd->clk[i], pd->pclk[i])) |
| 94 | 98 | pr_err("%s: error setting parent to clock%d\n", |
| 95 | 99 | pd->name, i); |
| @@ -117,27 +121,37 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain) · 21 unmodified lines | ||
| 117 | 121 | |
| 118 | 122 | static __init int exynos4_pm_init_power_domain(void) |
| 119 | 123 | { |
| 120 | − struct platform_device *pdev; | |
| 121 | 124 | struct device_node *np; |
| 122 | 125 | |
| 123 | 126 | for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { |
| 124 | 127 | struct exynos_pm_domain *pd; |
| 125 | 128 | int on, i; |
| 126 | − struct device *dev; | |
| 127 | − | |
| 128 | − pdev = of_find_device_by_node(np); | |
| 129 | − dev = &pdev->dev; | |
| 130 | 129 | |
| 131 | 130 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); |
| 132 | 131 | if (!pd) { |
| 133 | 132 | pr_err("%s: failed to allocate memory for domain\n", |
| 134 | 133 | __func__); |
| 134 | + of_node_put(np); | |
| 135 | + return -ENOMEM; | |
| 136 | + } | |
| 137 | + pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1, | |
| 138 | + GFP_KERNEL); | |
| 139 | + if (!pd->pd.name) { | |
| 140 | + kfree(pd); | |
| 141 | + of_node_put(np); | |
| 135 | 142 | return -ENOMEM; |
| 136 | 143 | } |
| 137 | 144 | |
| 138 | − pd->pd.name = kstrdup(dev_name(dev), GFP_KERNEL); | |
| 139 | 145 | pd->name = pd->pd.name; |
| 140 | 146 | pd->base = of_iomap(np, 0); |
| 147 | + if (!pd->base) { | |
| 148 | + pr_warn("%s: failed to map memory\n", __func__); | |
| 149 | + kfree(pd->pd.name); | |
| 150 | + kfree(pd); | |
| 151 | + of_node_put(np); | |
| 152 | + continue; | |
| 153 | + } | |
| 154 | + | |
| 141 | 155 | pd->pd.power_off = exynos_pd_power_off; |
| 142 | 156 | pd->pd.power_on = exynos_pd_power_on; |
| 143 | 157 | |
| @@ -145,12 +159,12 @@ static __init int exynos4_pm_init_power_domain(void) · 1 unmodified line | ||
| 145 | 159 | char clk_name[8]; |
| 146 | 160 | |
| 147 | 161 | snprintf(clk_name, sizeof(clk_name), "asb%d", i); |
| 148 | − pd->asb_clk[i] = clk_get(dev, clk_name); | |
| 162 | + pd->asb_clk[i] = of_clk_get_by_name(np, clk_name); | |
| 149 | 163 | if (IS_ERR(pd->asb_clk[i])) |
| 150 | 164 | break; |
| 151 | 165 | } |
| 152 | 166 | |
| 153 | − pd->oscclk = clk_get(dev, "oscclk"); | |
| 167 | + pd->oscclk = of_clk_get_by_name(np, "oscclk"); | |
| 154 | 168 | if (IS_ERR(pd->oscclk)) |
| 155 | 169 | goto no_clk; |
| 156 | 170 | |
| @@ -158,16 +172,14 @@ static __init int exynos4_pm_init_power_domain(void) · 1 unmodified line | ||
| 158 | 172 | char clk_name[8]; |
| 159 | 173 | |
| 160 | 174 | snprintf(clk_name, sizeof(clk_name), "clk%d", i); |
| 161 | − pd->clk[i] = clk_get(dev, clk_name); | |
| 175 | + pd->clk[i] = of_clk_get_by_name(np, clk_name); | |
| 162 | 176 | if (IS_ERR(pd->clk[i])) |
| 163 | 177 | break; |
| 164 | − snprintf(clk_name, sizeof(clk_name), "pclk%d", i); | |
| 165 | − pd->pclk[i] = clk_get(dev, clk_name); | |
| 166 | − if (IS_ERR(pd->pclk[i])) { | |
| 167 | − clk_put(pd->clk[i]); | |
| 168 | − pd->clk[i] = ERR_PTR(-EINVAL); | |
| 169 | − break; | |
| 170 | − } | |
| 178 | + /* | |
| 179 | + * Skip setting parent on first power up. | |
| 180 | + * The parent at this time may not be useful at all. | |
| 181 | + */ | |
| 182 | + pd->pclk[i] = ERR_PTR(-EINVAL); | |
| 171 | 183 | } |
| 172 | 184 | |
| 173 | 185 | if (IS_ERR(pd->clk[0])) |
| @@ -189,15 +201,15 @@ no_clk: · 15 unmodified lines | ||
| 189 | 201 | args.args_count = 0; |
| 190 | 202 | child_domain = of_genpd_get_from_provider(&args); |
| 191 | 203 | if (IS_ERR(child_domain)) |
| 192 | − continue; | |
| 204 | + goto next_pd; | |
| 193 | 205 | |
| 194 | 206 | if (of_parse_phandle_with_args(np, "power-domains", |
| 195 | 207 | "#power-domain-cells", 0, &args) != 0) |
| 196 | − continue; | |
| 208 | + goto next_pd; | |
| 197 | 209 | |
| 198 | 210 | parent_domain = of_genpd_get_from_provider(&args); |
| 199 | 211 | if (IS_ERR(parent_domain)) |
| 200 | − continue; | |
| 212 | + goto next_pd; | |
| 201 | 213 | |
| 202 | 214 | if (pm_genpd_add_subdomain(parent_domain, child_domain)) |
| 203 | 215 | pr_warn("%s failed to add subdomain: %s\n", |
| @@ -205,9 +217,10 @@ no_clk: · 1 unmodified line | ||
| 205 | 217 | else |
| 206 | 218 | pr_info("%s has as child subdomain: %s.\n", |
| 207 | 219 | parent_domain->name, child_domain->name); |
| 220 | +next_pd: | |
| 208 | 221 | of_node_put(np); |
| 209 | 222 | } |
| 210 | 223 | |
| 211 | 224 | return 0; |
| 212 | 225 | } |
| 213 | −arch_initcall(exynos4_pm_init_power_domain); | |
| 226 | +core_initcall(exynos4_pm_init_power_domain); | |
| @@ -681,7 +681,7 @@ static unsigned int const exynos5420_list_disable_pmu_reg[] = { · 680 unmodified lines | ||
| 681 | 681 | EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, |
| 682 | 682 | }; |
| 683 | 683 | |
| 684 | −static void exynos5_power_off(void) | |
| 684 | +static void exynos_power_off(void) | |
| 685 | 685 | { |
| 686 | 686 | unsigned int tmp; |
| 687 | 687 | |
| @@ -872,8 +872,6 @@ static void exynos5420_pmu_init(void) · 184 unmodified lines | ||
| 872 | 872 | EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI); |
| 873 | 873 | |
| 874 | 874 | pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER); |
| 875 | − | |
| 876 | − pm_power_off = exynos5_power_off; | |
| 877 | 875 | pr_info("EXYNOS5420 PMU initialized\n"); |
| 878 | 876 | } |
| 879 | 877 | |
| @@ -984,6 +982,8 @@ static int exynos_pmu_probe(struct platform_device *pdev) · 104 unmodified lines | ||
| 984 | 982 | if (ret) |
| 985 | 983 | dev_warn(dev, "can't register restart handler err=%d\n", ret); |
| 986 | 984 | |
| 985 | + pm_power_off = exynos_power_off; | |
| 986 | + | |
| 987 | 987 | dev_dbg(dev, "Exynos PMU Driver probe done\n"); |
| 988 | 988 | return 0; |
| 989 | 989 | } |
| @@ -223,7 +223,7 @@ static int exynos_pmu_domain_alloc(struct irq_domain *domain, · 222 unmodified lines | ||
| 223 | 223 | return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args); |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | −static struct irq_domain_ops exynos_pmu_domain_ops = { | |
| 226 | +static const struct irq_domain_ops exynos_pmu_domain_ops = { | |
| 227 | 227 | .xlate = exynos_pmu_domain_xlate, |
| 228 | 228 | .alloc = exynos_pmu_domain_alloc, |
| 229 | 229 | .free = irq_domain_free_irqs_common, |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | menuconfig ARCH_MXC |
| 2 | − bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 | |
| 2 | + bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M | |
| 3 | 3 | select ARCH_REQUIRE_GPIOLIB |
| 4 | 4 | select ARM_CPU_SUSPEND if PM |
| 5 | − select CLKSRC_MMIO | |
| 5 | + select CLKSRC_IMX_GPT | |
| 6 | 6 | select GENERIC_IRQ_CHIP |
| 7 | 7 | select PINCTRL |
| 8 | 8 | select PM_OPP if PM |
| @@ -462,10 +462,10 @@ config MACH_VPR200 · 453 unmodified lines | ||
| 462 | 462 | |
| 463 | 463 | endif |
| 464 | 464 | |
| 465 | −if ARCH_MULTI_V5 | |
| 466 | − | |
| 467 | 465 | comment "Device tree only" |
| 468 | 466 | |
| 467 | +if ARCH_MULTI_V5 | |
| 468 | + | |
| 469 | 469 | config SOC_IMX25 |
| 470 | 470 | bool "i.MX25 support" |
| 471 | 471 | select ARCH_MXC_IOMUX_V3 |
| @@ -478,7 +478,7 @@ endif · 6 unmodified lines | ||
| 478 | 478 | |
| 479 | 479 | if ARCH_MULTI_V7 |
| 480 | 480 | |
| 481 | −comment "Device tree only" | |
| 481 | +comment "Cortex-A platforms" | |
| 482 | 482 | |
| 483 | 483 | config SOC_IMX5 |
| 484 | 484 | bool |
| @@ -548,10 +548,33 @@ config SOC_IMX6SX · 63 unmodified lines | ||
| 548 | 548 | help |
| 549 | 549 | This enables support for Freescale i.MX6 SoloX processor. |
| 550 | 550 | |
| 551 | +config SOC_IMX7D | |
| 552 | + bool "i.MX7 Dual support" | |
| 553 | + select PINCTRL_IMX7D | |
| 554 | + select ARM_GIC | |
| 555 | + select HAVE_IMX_ANATOP | |
| 556 | + select HAVE_IMX_MMDC | |
| 557 | + help | |
| 558 | + This enables support for Freescale i.MX7 Dual processor. | |
| 559 | + | |
| 560 | +config SOC_LS1021A | |
| 561 | + bool "Freescale LS1021A support" | |
| 562 | + select ARM_GIC | |
| 563 | + select HAVE_ARM_ARCH_TIMER | |
| 564 | + select PCI_DOMAINS if PCI | |
| 565 | + select ZONE_DMA if ARM_LPAE | |
| 566 | + help | |
| 567 | + This enables support for Freescale LS1021A processor. | |
| 568 | + | |
| 569 | +endif | |
| 570 | + | |
| 571 | +comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms" | |
| 572 | + | |
| 573 | +if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M | |
| 574 | + | |
| 551 | 575 | config SOC_VF610 |
| 552 | 576 | bool "Vybrid Family VF610 support" |
| 553 | − select IRQ_DOMAIN_HIERARCHY | |
| 554 | − select ARM_GIC | |
| 577 | + select ARM_GIC if ARCH_MULTI_V7 | |
| 555 | 578 | select PINCTRL_VF610 |
| 556 | 579 | select PL310_ERRATA_769419 if CACHE_L2X0 |
| 557 | 580 | select SMP_ON_UP if SMP |
| @@ -565,7 +588,7 @@ choice · 7 unmodified lines | ||
| 565 | 588 | default VF_USE_ARM_GLOBAL_TIMER |
| 566 | 589 | |
| 567 | 590 | config VF_USE_ARM_GLOBAL_TIMER |
| 568 | − bool "Use ARM Global Timer" | |
| 591 | + bool "Use ARM Global Timer" if ARCH_MULTI_V7 | |
| 569 | 592 | select ARM_GLOBAL_TIMER |
| 570 | 593 | select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
| 571 | 594 | help |
| @@ -579,16 +602,6 @@ choice · 7 unmodified lines | ||
| 579 | 602 | |
| 580 | 603 | endchoice |
| 581 | 604 | |
| 582 | −config SOC_LS1021A | |
| 583 | − bool "Freescale LS1021A support" | |
| 584 | − select ARM_GIC | |
| 585 | − select HAVE_ARM_ARCH_TIMER | |
| 586 | − select PCI_DOMAINS if PCI | |
| 587 | − select ZONE_DMA if ARM_LPAE | |
| 588 | − | |
| 589 | − help | |
| 590 | − This enables support for Freescale LS1021A processor. | |
| 591 | − | |
| 592 | 605 | endif |
| 593 | 606 | |
| 594 | 607 | source "arch/arm/mach-imx/devices/Kconfig" |
| @@ -1,23 +1,18 @@ | ||
| 1 | −obj-y := time.o cpu.o system.o irq-common.o | |
| 1 | +obj-y := cpu.o system.o irq-common.o | |
| 2 | 2 | |
| 3 | −obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o | |
| 4 | −obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o | |
| 3 | +obj-$(CONFIG_SOC_IMX1) += mm-imx1.o | |
| 4 | +obj-$(CONFIG_SOC_IMX21) += mm-imx21.o | |
| 5 | 5 | |
| 6 | −obj-$(CONFIG_SOC_IMX25) += clk-imx25.o cpu-imx25.o mach-imx25.o | |
| 6 | +obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o | |
| 7 | 7 | |
| 8 | 8 | obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o |
| 9 | −obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o | |
| 9 | +obj-$(CONFIG_SOC_IMX27) += mm-imx27.o ehci-imx27.o | |
| 10 | 10 | |
| 11 | −obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o | |
| 12 | −obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o | |
| 11 | +obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o | |
| 12 | +obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o ehci-imx35.o pm-imx3.o | |
| 13 | 13 | |
| 14 | 14 | imx5-pm-$(CONFIG_PM) += pm-imx5.o |
| 15 | −obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o clk-cpu.o $(imx5-pm-y) | |
| 16 | − | |
| 17 | −obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ | |
| 18 | − clk-pfd.o clk-busy.o clk.o \ | |
| 19 | − clk-fixup-div.o clk-fixup-mux.o \ | |
| 20 | − clk-gate-exclusive.o | |
| 15 | +obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o $(imx5-pm-y) | |
| 21 | 16 | |
| 22 | 17 | obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o |
| 23 | 18 | obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o |
| @@ -85,13 +80,15 @@ AFLAGS_headsmp.o :=-Wa,-march=armv7-a · 61 unmodified lines | ||
| 85 | 80 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o |
| 86 | 81 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
| 87 | 82 | endif |
| 88 | −obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o | |
| 89 | −obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o | |
| 90 | −obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o mach-imx6sx.o | |
| 83 | +obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o | |
| 84 | +obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o | |
| 85 | +obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o | |
| 86 | +obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o | |
| 91 | 87 | |
| 92 | 88 | ifeq ($(CONFIG_SUSPEND),y) |
| 93 | 89 | AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a |
| 94 | 90 | obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o |
| 91 | +obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o | |
| 95 | 92 | endif |
| 96 | 93 | obj-$(CONFIG_SOC_IMX6) += pm-imx6.o |
| 97 | 94 | |
| @@ -99,7 +96,7 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o · 1 unmodified line | ||
| 99 | 96 | obj-$(CONFIG_SOC_IMX51) += mach-imx51.o |
| 100 | 97 | obj-$(CONFIG_SOC_IMX53) += mach-imx53.o |
| 101 | 98 | |
| 102 | −obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o | |
| 99 | +obj-$(CONFIG_SOC_VF610) += mach-vf610.o | |
| 103 | 100 | |
| 104 | 101 | obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o |
| 105 | 102 | |
Empty file added.
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | − * Copyright (C) 2013 Freescale Semiconductor, Inc. | |
| 2 | + * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. | |
| 3 | 3 | * |
| 4 | 4 | * The code contained herein is licensed under the GNU General Public |
| 5 | 5 | * License. You may obtain a copy of the GNU General Public License |
| @@ -28,6 +28,7 @@ · 22 unmodified lines | ||
| 28 | 28 | #define ANADIG_USB2_CHRG_DETECT 0x210 |
| 29 | 29 | #define ANADIG_DIGPROG 0x260 |
| 30 | 30 | #define ANADIG_DIGPROG_IMX6SL 0x280 |
| 31 | +#define ANADIG_DIGPROG_IMX7D 0x800 | |
| 31 | 32 | |
| 32 | 33 | #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 |
| 33 | 34 | #define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8 |
| @@ -121,6 +122,8 @@ void __init imx_init_revision_from_anatop(void) · 87 unmodified lines | ||
| 121 | 122 | WARN_ON(!anatop_base); |
| 122 | 123 | if (of_device_is_compatible(np, "fsl,imx6sl-anatop")) |
| 123 | 124 | offset = ANADIG_DIGPROG_IMX6SL; |
| 125 | + if (of_device_is_compatible(np, "fsl,imx7d-anatop")) | |
| 126 | + offset = ANADIG_DIGPROG_IMX7D; | |
| 124 | 127 | digprog = readl_relaxed(anatop_base + offset); |
| 125 | 128 | iounmap(anatop_base); |
| 126 | 129 | |
| @@ -44,7 +44,6 @@ void imx27_soc_init(void); · 43 unmodified lines | ||
| 44 | 44 | void imx31_soc_init(void); |
| 45 | 45 | void imx35_soc_init(void); |
| 46 | 46 | void epit_timer_init(void __iomem *base, int irq); |
| 47 | −void mxc_timer_init(void __iomem *, int); | |
| 48 | 47 | int mx1_clocks_init(unsigned long fref); |
| 49 | 48 | int mx21_clocks_init(unsigned long lref, unsigned long fref); |
| 50 | 49 | int mx27_clocks_init(unsigned long fref); |
| @@ -56,13 +55,10 @@ struct platform_device *mxc_register_gpio(char *name, int id, · 5 unmodified lines | ||
| 56 | 55 | void mxc_set_cpu_type(unsigned int type); |
| 57 | 56 | void mxc_restart(enum reboot_mode, const char *); |
| 58 | 57 | void mxc_arch_reset_init(void __iomem *); |
| 59 | −int mx51_revision(void); | |
| 60 | −int mx53_revision(void); | |
| 61 | 58 | void imx_set_aips(void __iomem *); |
| 62 | 59 | void imx_aips_allow_unprivileged_access(const char *compat); |
| 63 | 60 | int mxc_device_init(void); |
| 64 | 61 | void imx_set_soc_revision(unsigned int rev); |
| 65 | −unsigned int imx_get_soc_revision(void); | |
| 66 | 62 | void imx_init_revision_from_anatop(void); |
| 67 | 63 | struct device *imx_soc_device_init(void); |
| 68 | 64 | void imx6_enable_rbc(bool enable); |
| @@ -87,7 +83,6 @@ enum mx3_cpu_pwr_mode { · 18 unmodified lines | ||
| 87 | 83 | }; |
| 88 | 84 | |
| 89 | 85 | void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); |
| 90 | −void imx_print_silicon_rev(const char *cpu, int srev); | |
| 91 | 86 | |
| 92 | 87 | void imx_enable_cpu(int cpu, bool enable); |
| 93 | 88 | void imx_set_cpu_jump(int cpu, void *jump_addr); |
| @@ -111,7 +106,7 @@ void imx_gpc_hwirq_unmask(unsigned int hwirq); · 17 unmodified lines | ||
| 111 | 106 | void imx_anatop_init(void); |
| 112 | 107 | void imx_anatop_pre_suspend(void); |
| 113 | 108 | void imx_anatop_post_resume(void); |
| 114 | −int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); | |
| 109 | +int imx6_set_lpm(enum mxc_cpu_pwr_mode mode); | |
| 115 | 110 | void imx6q_set_int_mem_clk_lpm(bool enable); |
| 116 | 111 | void imx6sl_set_wait_clk(bool enter); |
| 117 | 112 | int imx_mmdc_get_ddr_type(void); |
| @@ -121,26 +116,28 @@ int imx_cpu_kill(unsigned int cpu); · 3 unmodified lines | ||
| 121 | 116 | |
| 122 | 117 | #ifdef CONFIG_SUSPEND |
| 123 | 118 | void v7_cpu_resume(void); |
| 119 | +void imx53_suspend(void __iomem *ocram_vbase); | |
| 120 | +extern const u32 imx53_suspend_sz; | |
| 124 | 121 | void imx6_suspend(void __iomem *ocram_vbase); |
| 125 | 122 | #else |
| 126 | 123 | static inline void v7_cpu_resume(void) {} |
| 124 | +static inline void imx53_suspend(void __iomem *ocram_vbase) {} | |
| 125 | +static const u32 imx53_suspend_sz; | |
| 127 | 126 | static inline void imx6_suspend(void __iomem *ocram_vbase) {} |
| 128 | 127 | #endif |
| 129 | 128 | |
| 129 | +void imx6_pm_ccm_init(const char *ccm_compat); | |
| 130 | 130 | void imx6q_pm_init(void); |
| 131 | 131 | void imx6dl_pm_init(void); |
| 132 | 132 | void imx6sl_pm_init(void); |
| 133 | 133 | void imx6sx_pm_init(void); |
| 134 | −void imx6q_pm_set_ccm_base(void __iomem *base); | |
| 135 | 134 | |
| 136 | 135 | #ifdef CONFIG_PM |
| 137 | 136 | void imx51_pm_init(void); |
| 138 | 137 | void imx53_pm_init(void); |
| 139 | −void imx5_pm_set_ccm_base(void __iomem *base); | |
| 140 | 138 | #else |
| 141 | 139 | static inline void imx51_pm_init(void) {} |
| 142 | 140 | static inline void imx53_pm_init(void) {} |
| 143 | −static inline void imx5_pm_set_ccm_base(void __iomem *base) {} | |
| 144 | 141 | #endif |
| 145 | 142 | |
| 146 | 143 | #ifdef CONFIG_NEON |
| @@ -130,6 +130,9 @@ struct device * __init imx_soc_device_init(void) · 129 unmodified lines | ||
| 130 | 130 | case MXC_CPU_IMX6Q: |
| 131 | 131 | soc_id = "i.MX6Q"; |
| 132 | 132 | break; |
| 133 | + case MXC_CPU_IMX7D: | |
| 134 | + soc_id = "i.MX7D"; | |
| 135 | + break; | |
| 133 | 136 | default: |
| 134 | 137 | soc_id = "Unknown"; |
| 135 | 138 | } |
| @@ -27,9 +27,9 @@ static int imx6q_enter_wait(struct cpuidle_device *dev, · 26 unmodified lines | ||
| 27 | 27 | */ |
| 28 | 28 | if (!spin_trylock(&master_lock)) |
| 29 | 29 | goto idle; |
| 30 | − imx6q_set_lpm(WAIT_UNCLOCKED); | |
| 30 | + imx6_set_lpm(WAIT_UNCLOCKED); | |
| 31 | 31 | cpu_do_idle(); |
| 32 | − imx6q_set_lpm(WAIT_CLOCKED); | |
| 32 | + imx6_set_lpm(WAIT_CLOCKED); | |
| 33 | 33 | spin_unlock(&master_lock); |
| 34 | 34 | goto done; |
| 35 | 35 | } |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | static int imx6sl_enter_wait(struct cpuidle_device *dev, |
| 17 | 17 | struct cpuidle_driver *drv, int index) |
| 18 | 18 | { |
| 19 | − imx6q_set_lpm(WAIT_UNCLOCKED); | |
| 19 | + imx6_set_lpm(WAIT_UNCLOCKED); | |
| 20 | 20 | /* |
| 21 | 21 | * Software workaround for ERR005311, see function |
| 22 | 22 | * description for details. |
| @@ -24,7 +24,7 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev, · 1 unmodified line | ||
| 24 | 24 | imx6sl_set_wait_clk(true); |
| 25 | 25 | cpu_do_idle(); |
| 26 | 26 | imx6sl_set_wait_clk(false); |
| 27 | − imx6q_set_lpm(WAIT_CLOCKED); | |
| 27 | + imx6_set_lpm(WAIT_CLOCKED); | |
| 28 | 28 | |
| 29 | 29 | return index; |
| 30 | 30 | } |
| @@ -25,7 +25,7 @@ static int imx6sx_idle_finish(unsigned long val) · 24 unmodified lines | ||
| 25 | 25 | static int imx6sx_enter_wait(struct cpuidle_device *dev, |
| 26 | 26 | struct cpuidle_driver *drv, int index) |
| 27 | 27 | { |
| 28 | − imx6q_set_lpm(WAIT_UNCLOCKED); | |
| 28 | + imx6_set_lpm(WAIT_UNCLOCKED); | |
| 29 | 29 | |
| 30 | 30 | switch (index) { |
| 31 | 31 | case 1: |
| @@ -50,7 +50,7 @@ static int imx6sx_enter_wait(struct cpuidle_device *dev, · 18 unmodified lines | ||
| 50 | 50 | break; |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | − imx6q_set_lpm(WAIT_CLOCKED); | |
| 53 | + imx6_set_lpm(WAIT_CLOCKED); | |
| 54 | 54 | |
| 55 | 55 | return index; |
| 56 | 56 | } |
| @@ -227,7 +227,7 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain, · 226 unmodified lines | ||
| 227 | 227 | return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args); |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | −static struct irq_domain_ops imx_gpc_domain_ops = { | |
| 230 | +static const struct irq_domain_ops imx_gpc_domain_ops = { | |
| 231 | 231 | .xlate = imx_gpc_domain_xlate, |
| 232 | 232 | .alloc = imx_gpc_domain_alloc, |
| 233 | 233 | .free = irq_domain_free_irqs_common, |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #ifndef __ASSEMBLY__ |
| 24 | 24 | #include <asm/io.h> |
| 25 | +#include <soc/imx/revision.h> | |
| 25 | 26 | #endif |
| 26 | 27 | #include <asm/sizes.h> |
| 27 | 28 | |
| @@ -40,7 +40,7 @@ static DEFINE_SPINLOCK(gpio_mux_lock); · 39 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) |
| 42 | 42 | |
| 43 | −static unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG]; | |
| 43 | +static DECLARE_BITMAP(mxc_pin_alloc_map, NB_PORTS * 32); | |
| 44 | 44 | /* |
| 45 | 45 | * set the mode for a IOMUX pin. |
| 46 | 46 | */ |
| @@ -393,6 +393,7 @@ static void __init imx6q_init_irq(void) · 392 unmodified lines | ||
| 393 | 393 | imx_init_l2cache(); |
| 394 | 394 | imx_src_init(); |
| 395 | 395 | irqchip_init(); |
| 396 | + imx6_pm_ccm_init("fsl,imx6q-ccm"); | |
| 396 | 397 | } |
| 397 | 398 | |
| 398 | 399 | static const char * const imx6q_dt_compat[] __initconst = { |
| @@ -66,6 +66,7 @@ static void __init imx6sl_init_irq(void) · 65 unmodified lines | ||
| 66 | 66 | imx_init_l2cache(); |
| 67 | 67 | imx_src_init(); |
| 68 | 68 | irqchip_init(); |
| 69 | + imx6_pm_ccm_init("fsl,imx6sl-ccm"); | |
| 69 | 70 | } |
| 70 | 71 | |
| 71 | 72 | static const char * const imx6sl_dt_compat[] __initconst = { |
| @@ -86,6 +86,7 @@ static void __init imx6sx_init_irq(void) · 85 unmodified lines | ||
| 86 | 86 | imx_init_l2cache(); |
| 87 | 87 | imx_src_init(); |
| 88 | 88 | irqchip_init(); |
| 89 | + imx6_pm_ccm_init("fsl,imx6sx-ccm"); | |
| 89 | 90 | } |
| 90 | 91 | |
| 91 | 92 | static void __init imx6sx_init_late(void) |
| @@ -0,0 +1,43 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 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 | +#include <linux/irqchip.h> | |
| 9 | +#include <linux/of_platform.h> | |
| 10 | +#include <asm/mach/arch.h> | |
| 11 | +#include <asm/mach/map.h> | |
| 12 | + | |
| 13 | +#include "common.h" | |
| 14 | + | |
| 15 | +static void __init imx7d_init_machine(void) | |
| 16 | +{ | |
| 17 | + struct device *parent; | |
| 18 | + | |
| 19 | + parent = imx_soc_device_init(); | |
| 20 | + if (parent == NULL) | |
| 21 | + pr_warn("failed to initialize soc device\n"); | |
| 22 | + | |
| 23 | + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | |
| 24 | + imx_anatop_init(); | |
| 25 | +} | |
| 26 | + | |
| 27 | +static void __init imx7d_init_irq(void) | |
| 28 | +{ | |
| 29 | + imx_init_revision_from_anatop(); | |
| 30 | + imx_src_init(); | |
| 31 | + irqchip_init(); | |
| 32 | +} | |
| 33 | + | |
| 34 | +static const char *imx7d_dt_compat[] __initconst = { | |
| 35 | + "fsl,imx7d", | |
| 36 | + NULL, | |
| 37 | +}; | |
| 38 | + | |
| 39 | +DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)") | |
| 40 | + .init_irq = imx7d_init_irq, | |
| 41 | + .init_machine = imx7d_init_machine, | |
| 42 | + .dt_compat = imx7d_dt_compat, | |
| 43 | +MACHINE_END | |
| @@ -17,6 +17,7 @@ static const char * const vf610_dt_compat[] __initconst = { · 16 unmodified lines | ||
| 17 | 17 | "fsl,vf510", |
| 18 | 18 | "fsl,vf600", |
| 19 | 19 | "fsl,vf610", |
| 20 | + "fsl,vf610m4", | |
| 20 | 21 | NULL, |
| 21 | 22 | }; |
| 22 | 23 | |
| @@ -17,6 +17,8 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/of_address.h> |
| 18 | 18 | #include <linux/of_device.h> |
| 19 | 19 | |
| 20 | +#include "common.h" | |
| 21 | + | |
| 20 | 22 | #define MMDC_MAPSR 0x404 |
| 21 | 23 | #define BP_MMDC_MAPSR_PSD 0 |
| 22 | 24 | #define BP_MMDC_MAPSR_PSS 4 |
| @@ -231,8 +231,4 @@ · 230 unmodified lines | ||
| 231 | 231 | #define MX27_DMA_REQ_SDHC3 36 |
| 232 | 232 | #define MX27_DMA_REQ_NFC 37 |
| 233 | 233 | |
| 234 | −#ifndef __ASSEMBLY__ | |
| 235 | −extern int mx27_revision(void); | |
| 236 | −#endif | |
| 237 | − | |
| 238 | 234 | #endif /* ifndef __MACH_MX27_H__ */ |
| @@ -185,11 +185,4 @@ · 184 unmodified lines | ||
| 185 | 185 | |
| 186 | 186 | #define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */ |
| 187 | 187 | |
| 188 | −/* Mandatory defines used globally */ | |
| 189 | − | |
| 190 | −#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) | |
| 191 | −extern int mx35_revision(void); | |
| 192 | −extern int mx31_revision(void); | |
| 193 | −#endif | |
| 194 | − | |
| 195 | 188 | #endif /* ifndef __MACH_MX3x_H__ */ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | − * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved. | |
| 2 | + * Copyright 2004-2007, 2010-2015 Freescale Semiconductor, Inc. | |
| 3 | 3 | * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) |
| 4 | 4 | * |
| 5 | 5 | * This program is free software; you can redistribute it and/or |
| @@ -38,22 +38,7 @@ · 32 unmodified lines | ||
| 38 | 38 | #define MXC_CPU_IMX6DL 0x61 |
| 39 | 39 | #define MXC_CPU_IMX6SX 0x62 |
| 40 | 40 | #define MXC_CPU_IMX6Q 0x63 |
| 41 | − | |
| 42 | −#define IMX_CHIP_REVISION_1_0 0x10 | |
| 43 | −#define IMX_CHIP_REVISION_1_1 0x11 | |
| 44 | −#define IMX_CHIP_REVISION_1_2 0x12 | |
| 45 | −#define IMX_CHIP_REVISION_1_3 0x13 | |
| 46 | −#define IMX_CHIP_REVISION_1_4 0x14 | |
| 47 | −#define IMX_CHIP_REVISION_1_5 0x15 | |
| 48 | −#define IMX_CHIP_REVISION_2_0 0x20 | |
| 49 | −#define IMX_CHIP_REVISION_2_1 0x21 | |
| 50 | −#define IMX_CHIP_REVISION_2_2 0x22 | |
| 51 | −#define IMX_CHIP_REVISION_2_3 0x23 | |
| 52 | −#define IMX_CHIP_REVISION_3_0 0x30 | |
| 53 | −#define IMX_CHIP_REVISION_3_1 0x31 | |
| 54 | −#define IMX_CHIP_REVISION_3_2 0x32 | |
| 55 | −#define IMX_CHIP_REVISION_3_3 0x33 | |
| 56 | −#define IMX_CHIP_REVISION_UNKNOWN 0xff | |
| 41 | +#define MXC_CPU_IMX7D 0x72 | |
| 57 | 42 | |
| 58 | 43 | #define IMX_DDR_TYPE_LPDDR2 1 |
| 59 | 44 | |
| @@ -185,6 +170,11 @@ static inline bool cpu_is_imx6q(void) · 125 unmodified lines | ||
| 185 | 170 | return __mxc_cpu_type == MXC_CPU_IMX6Q; |
| 186 | 171 | } |
| 187 | 172 | |
| 173 | +static inline bool cpu_is_imx7d(void) | |
| 174 | +{ | |
| 175 | + return __mxc_cpu_type == MXC_CPU_IMX7D; | |
| 176 | +} | |
| 177 | + | |
| 188 | 178 | struct cpu_op { |
| 189 | 179 | u32 cpu_rate; |
| 190 | 180 | }; |
| @@ -13,7 +13,14 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/io.h> |
| 14 | 14 | #include <linux/err.h> |
| 15 | 15 | #include <linux/export.h> |
| 16 | + | |
| 17 | +#include <linux/genalloc.h> | |
| 18 | +#include <linux/of.h> | |
| 19 | +#include <linux/of_address.h> | |
| 20 | +#include <linux/of_platform.h> | |
| 21 | + | |
| 16 | 22 | #include <asm/cacheflush.h> |
| 23 | +#include <asm/fncpy.h> | |
| 17 | 24 | #include <asm/system_misc.h> |
| 18 | 25 | #include <asm/tlbflush.h> |
| 19 | 26 | |
| @@ -49,29 +56,91 @@ · 29 unmodified lines | ||
| 49 | 56 | */ |
| 50 | 57 | #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF |
| 51 | 58 | |
| 59 | +struct imx5_suspend_io_state { | |
| 60 | + u32 offset; | |
| 61 | + u32 clear; | |
| 62 | + u32 set; | |
| 63 | + u32 saved_value; | |
| 64 | +}; | |
| 65 | + | |
| 52 | 66 | struct imx5_pm_data { |
| 67 | + phys_addr_t ccm_addr; | |
| 53 | 68 | phys_addr_t cortex_addr; |
| 54 | 69 | phys_addr_t gpc_addr; |
| 70 | + phys_addr_t m4if_addr; | |
| 71 | + phys_addr_t iomuxc_addr; | |
| 72 | + void (*suspend_asm)(void __iomem *ocram_vbase); | |
| 73 | + const u32 *suspend_asm_sz; | |
| 74 | + const struct imx5_suspend_io_state *suspend_io_config; | |
| 75 | + int suspend_io_count; | |
| 76 | +}; | |
| 77 | + | |
| 78 | +static const struct imx5_suspend_io_state imx53_suspend_io_config[] = { | |
| 79 | +#define MX53_DSE_HIGHZ_MASK (0x7 << 19) | |
| 80 | + {.offset = 0x584, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM0 */ | |
| 81 | + {.offset = 0x594, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM1 */ | |
| 82 | + {.offset = 0x560, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM2 */ | |
| 83 | + {.offset = 0x554, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM3 */ | |
| 84 | + {.offset = 0x574, .clear = MX53_DSE_HIGHZ_MASK}, /* CAS */ | |
| 85 | + {.offset = 0x588, .clear = MX53_DSE_HIGHZ_MASK}, /* RAS */ | |
| 86 | + {.offset = 0x578, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_0 */ | |
| 87 | + {.offset = 0x570, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_1 */ | |
| 88 | + | |
| 89 | + {.offset = 0x580, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT0 */ | |
| 90 | + {.offset = 0x564, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT1 */ | |
| 91 | + {.offset = 0x57c, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS0 */ | |
| 92 | + {.offset = 0x590, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS1 */ | |
| 93 | + {.offset = 0x568, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS2 */ | |
| 94 | + {.offset = 0x558, .clear = MX53_DSE_HIGHZ_MASK}, /* SDSQ3 */ | |
| 95 | + {.offset = 0x6f0, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_ADDS */ | |
| 96 | + {.offset = 0x718, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_BODS */ | |
| 97 | + {.offset = 0x71c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B1DS */ | |
| 98 | + {.offset = 0x728, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B2DS */ | |
| 99 | + {.offset = 0x72c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B3DS */ | |
| 100 | + | |
| 101 | + /* Controls the CKE signal which is required to leave self refresh */ | |
| 102 | + {.offset = 0x720, .clear = MX53_DSE_HIGHZ_MASK, .set = 1 << 19}, /* CTLDS */ | |
| 55 | 103 | }; |
| 56 | 104 | |
| 57 | 105 | static const struct imx5_pm_data imx51_pm_data __initconst = { |
| 106 | + .ccm_addr = 0x73fd4000, | |
| 58 | 107 | .cortex_addr = 0x83fa0000, |
| 59 | 108 | .gpc_addr = 0x73fd8000, |
| 60 | 109 | }; |
| 61 | 110 | |
| 62 | 111 | static const struct imx5_pm_data imx53_pm_data __initconst = { |
| 112 | + .ccm_addr = 0x53fd4000, | |
| 63 | 113 | .cortex_addr = 0x63fa0000, |
| 64 | 114 | .gpc_addr = 0x53fd8000, |
| 115 | + .m4if_addr = 0x63fd8000, | |
| 116 | + .iomuxc_addr = 0x53fa8000, | |
| 117 | + .suspend_asm = &imx53_suspend, | |
| 118 | + .suspend_asm_sz = &imx53_suspend_sz, | |
| 119 | + .suspend_io_config = imx53_suspend_io_config, | |
| 120 | + .suspend_io_count = ARRAY_SIZE(imx53_suspend_io_config), | |
| 65 | 121 | }; |
| 66 | 122 | |
| 123 | +#define MX5_MAX_SUSPEND_IOSTATE ARRAY_SIZE(imx53_suspend_io_config) | |
| 124 | + | |
| 125 | +/* | |
| 126 | + * This structure is for passing necessary data for low level ocram | |
| 127 | + * suspend code(arch/arm/mach-imx/suspend-imx53.S), if this struct | |
| 128 | + * definition is changed, the offset definition in that file | |
| 129 | + * must be also changed accordingly otherwise, the suspend to ocram | |
| 130 | + * function will be broken! | |
| 131 | + */ | |
| 132 | +struct imx5_cpu_suspend_info { | |
| 133 | + void __iomem *m4if_base; | |
| 134 | + void __iomem *iomuxc_base; | |
| 135 | + u32 io_count; | |
| 136 | + struct imx5_suspend_io_state io_state[MX5_MAX_SUSPEND_IOSTATE]; | |
| 137 | +} __aligned(8); | |
| 138 | + | |
| 67 | 139 | static void __iomem *ccm_base; |
| 68 | 140 | static void __iomem *cortex_base; |
| 69 | 141 | static void __iomem *gpc_base; |
| 70 | − | |
| 71 | −void __init imx5_pm_set_ccm_base(void __iomem *base) | |
| 72 | −{ | |
| 73 | − ccm_base = base; | |
| 74 | −} | |
| 142 | +static void __iomem *suspend_ocram_base; | |
| 143 | +static void (*imx5_suspend_in_ocram_fn)(void __iomem *ocram_vbase); | |
| 75 | 144 | |
| 76 | 145 | /* |
| 77 | 146 | * set cpu low power mode before WFI instruction. This function is called |
| @@ -161,8 +230,15 @@ static int mx5_suspend_enter(suspend_state_t state) · 83 unmodified lines | ||
| 161 | 230 | /*clear the EMPGC0/1 bits */ |
| 162 | 231 | __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); |
| 163 | 232 | __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); |
| 233 | + | |
| 234 | + if (imx5_suspend_in_ocram_fn) | |
| 235 | + imx5_suspend_in_ocram_fn(suspend_ocram_base); | |
| 236 | + else | |
| 237 | + cpu_do_idle(); | |
| 238 | + | |
| 239 | + } else { | |
| 240 | + cpu_do_idle(); | |
| 164 | 241 | } |
| 165 | − cpu_do_idle(); | |
| 166 | 242 | |
| 167 | 243 | /* return registers to default idle state */ |
| 168 | 244 | mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); |
| @@ -194,6 +270,111 @@ static void imx5_pm_idle(void) · 25 unmodified lines | ||
| 194 | 270 | imx5_cpu_do_idle(); |
| 195 | 271 | } |
| 196 | 272 | |
| 273 | +static int __init imx_suspend_alloc_ocram( | |
| 274 | + size_t size, | |
| 275 | + void __iomem **virt_out, | |
| 276 | + phys_addr_t *phys_out) | |
| 277 | +{ | |
| 278 | + struct device_node *node; | |
| 279 | + struct platform_device *pdev; | |
| 280 | + struct gen_pool *ocram_pool; | |
| 281 | + unsigned long ocram_base; | |
| 282 | + void __iomem *virt; | |
| 283 | + phys_addr_t phys; | |
| 284 | + int ret = 0; | |
| 285 | + | |
| 286 | + /* Copied from imx6: TODO factorize */ | |
| 287 | + node = of_find_compatible_node(NULL, NULL, "mmio-sram"); | |
| 288 | + if (!node) { | |
| 289 | + pr_warn("%s: failed to find ocram node!\n", __func__); | |
| 290 | + return -ENODEV; | |
| 291 | + } | |
| 292 | + | |
| 293 | + pdev = of_find_device_by_node(node); | |
| 294 | + if (!pdev) { | |
| 295 | + pr_warn("%s: failed to find ocram device!\n", __func__); | |
| 296 | + ret = -ENODEV; | |
| 297 | + goto put_node; | |
| 298 | + } | |
| 299 | + | |
| 300 | + ocram_pool = dev_get_gen_pool(&pdev->dev); | |
| 301 | + if (!ocram_pool) { | |
| 302 | + pr_warn("%s: ocram pool unavailable!\n", __func__); | |
| 303 | + ret = -ENODEV; | |
| 304 | + goto put_node; | |
| 305 | + } | |
| 306 | + | |
| 307 | + ocram_base = gen_pool_alloc(ocram_pool, size); | |
| 308 | + if (!ocram_base) { | |
| 309 | + pr_warn("%s: unable to alloc ocram!\n", __func__); | |
| 310 | + ret = -ENOMEM; | |
| 311 | + goto put_node; | |
| 312 | + } | |
| 313 | + | |
| 314 | + phys = gen_pool_virt_to_phys(ocram_pool, ocram_base); | |
| 315 | + virt = __arm_ioremap_exec(phys, size, false); | |
| 316 | + if (phys_out) | |
| 317 | + *phys_out = phys; | |
| 318 | + if (virt_out) | |
| 319 | + *virt_out = virt; | |
| 320 | + | |
| 321 | +put_node: | |
| 322 | + of_node_put(node); | |
| 323 | + | |
| 324 | + return ret; | |
| 325 | +} | |
| 326 | + | |
| 327 | +static int __init imx5_suspend_init(const struct imx5_pm_data *soc_data) | |
| 328 | +{ | |
| 329 | + struct imx5_cpu_suspend_info *suspend_info; | |
| 330 | + int ret; | |
| 331 | + /* Need this to avoid compile error due to const typeof in fncpy.h */ | |
| 332 | + void (*suspend_asm)(void __iomem *) = soc_data->suspend_asm; | |
| 333 | + | |
| 334 | + if (!suspend_asm) | |
| 335 | + return 0; | |
| 336 | + | |
| 337 | + if (!soc_data->suspend_asm_sz || !*soc_data->suspend_asm_sz) | |
| 338 | + return -EINVAL; | |
| 339 | + | |
| 340 | + ret = imx_suspend_alloc_ocram( | |
| 341 | + *soc_data->suspend_asm_sz + sizeof(*suspend_info), | |
| 342 | + &suspend_ocram_base, NULL); | |
| 343 | + if (ret) | |
| 344 | + return ret; | |
| 345 | + | |
| 346 | + suspend_info = suspend_ocram_base; | |
| 347 | + | |
| 348 | + suspend_info->io_count = soc_data->suspend_io_count; | |
| 349 | + memcpy(suspend_info->io_state, soc_data->suspend_io_config, | |
| 350 | + sizeof(*suspend_info->io_state) * soc_data->suspend_io_count); | |
| 351 | + | |
| 352 | + suspend_info->m4if_base = ioremap(soc_data->m4if_addr, SZ_16K); | |
| 353 | + if (!suspend_info->m4if_base) { | |
| 354 | + ret = -ENOMEM; | |
| 355 | + goto failed_map_m4if; | |
| 356 | + } | |
| 357 | + | |
| 358 | + suspend_info->iomuxc_base = ioremap(soc_data->iomuxc_addr, SZ_16K); | |
| 359 | + if (!suspend_info->iomuxc_base) { | |
| 360 | + ret = -ENOMEM; | |
| 361 | + goto failed_map_iomuxc; | |
| 362 | + } | |
| 363 | + | |
| 364 | + imx5_suspend_in_ocram_fn = fncpy( | |
| 365 | + suspend_ocram_base + sizeof(*suspend_info), | |
| 366 | + suspend_asm, | |
| 367 | + *soc_data->suspend_asm_sz); | |
| 368 | + | |
| 369 | + return 0; | |
| 370 | + | |
| 371 | +failed_map_iomuxc: | |
| 372 | + iounmap(suspend_info->m4if_base); | |
| 373 | + | |
| 374 | +failed_map_m4if: | |
| 375 | + return ret; | |
| 376 | +} | |
| 377 | + | |
| 197 | 378 | static int __init imx5_pm_common_init(const struct imx5_pm_data *data) |
| 198 | 379 | { |
| 199 | 380 | int ret; |
| @@ -208,6 +389,7 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) · 8 unmodified lines | ||
| 208 | 389 | |
| 209 | 390 | arm_pm_idle = imx5_pm_idle; |
| 210 | 391 | |
| 392 | + ccm_base = ioremap(data->ccm_addr, SZ_16K); | |
| 211 | 393 | cortex_base = ioremap(data->cortex_addr, SZ_16K); |
| 212 | 394 | gpc_base = ioremap(data->gpc_addr, SZ_16K); |
| 213 | 395 | WARN_ON(!ccm_base || !cortex_base || !gpc_base); |
| @@ -219,6 +401,11 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) · 5 unmodified lines | ||
| 219 | 401 | if (ret) |
| 220 | 402 | pr_warn("%s: cpuidle init failed %d\n", __func__, ret); |
| 221 | 403 | |
| 404 | + ret = imx5_suspend_init(data); | |
| 405 | + if (ret) | |
| 406 | + pr_warn("%s: No DDR LPM support with suspend %d!\n", | |
| 407 | + __func__, ret); | |
| 408 | + | |
| 222 | 409 | suspend_set_ops(&mx5_suspend_ops); |
| 223 | 410 | |
| 224 | 411 | return 0; |
| @@ -226,10 +413,12 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) · 1 unmodified line | ||
| 226 | 413 | |
| 227 | 414 | void __init imx51_pm_init(void) |
| 228 | 415 | { |
| 229 | − imx5_pm_common_init(&imx51_pm_data); | |
| 416 | + if (IS_ENABLED(CONFIG_SOC_IMX51)) | |
| 417 | + imx5_pm_common_init(&imx51_pm_data); | |
| 230 | 418 | } |
| 231 | 419 | |
| 232 | 420 | void __init imx53_pm_init(void) |
| 233 | 421 | { |
| 234 | − imx5_pm_common_init(&imx53_pm_data); | |
| 422 | + if (IS_ENABLED(CONFIG_SOC_IMX53)) | |
| 423 | + imx5_pm_common_init(&imx53_pm_data); | |
| 235 | 424 | } |
| @@ -255,7 +255,7 @@ static void imx6q_enable_wb(bool enable) · 254 unmodified lines | ||
| 255 | 255 | writel_relaxed(val, ccm_base + CCR); |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | −int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | |
| 258 | +int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) | |
| 259 | 259 | { |
| 260 | 260 | u32 val = readl_relaxed(ccm_base + CLPCR); |
| 261 | 261 | |
| @@ -340,7 +340,7 @@ static int imx6q_pm_enter(suspend_state_t state) · 78 unmodified lines | ||
| 340 | 340 | { |
| 341 | 341 | switch (state) { |
| 342 | 342 | case PM_SUSPEND_STANDBY: |
| 343 | − imx6q_set_lpm(STOP_POWER_ON); | |
| 343 | + imx6_set_lpm(STOP_POWER_ON); | |
| 344 | 344 | imx6q_set_int_mem_clk_lpm(true); |
| 345 | 345 | imx_gpc_pre_suspend(false); |
| 346 | 346 | if (cpu_is_imx6sl()) |
| @@ -350,10 +350,10 @@ static int imx6q_pm_enter(suspend_state_t state) · 3 unmodified lines | ||
| 350 | 350 | if (cpu_is_imx6sl()) |
| 351 | 351 | imx6sl_set_wait_clk(false); |
| 352 | 352 | imx_gpc_post_resume(); |
| 353 | − imx6q_set_lpm(WAIT_CLOCKED); | |
| 353 | + imx6_set_lpm(WAIT_CLOCKED); | |
| 354 | 354 | break; |
| 355 | 355 | case PM_SUSPEND_MEM: |
| 356 | − imx6q_set_lpm(STOP_POWER_OFF); | |
| 356 | + imx6_set_lpm(STOP_POWER_OFF); | |
| 357 | 357 | imx6q_set_int_mem_clk_lpm(false); |
| 358 | 358 | imx6q_enable_wb(true); |
| 359 | 359 | /* |
| @@ -373,7 +373,7 @@ static int imx6q_pm_enter(suspend_state_t state) · 13 unmodified lines | ||
| 373 | 373 | imx6_enable_rbc(false); |
| 374 | 374 | imx6q_enable_wb(false); |
| 375 | 375 | imx6q_set_int_mem_clk_lpm(true); |
| 376 | − imx6q_set_lpm(WAIT_CLOCKED); | |
| 376 | + imx6_set_lpm(WAIT_CLOCKED); | |
| 377 | 377 | break; |
| 378 | 378 | default: |
| 379 | 379 | return -EINVAL; |
| @@ -392,11 +392,6 @@ static const struct platform_suspend_ops imx6q_pm_ops = { · 12 unmodified lines | ||
| 392 | 392 | .valid = imx6q_pm_valid, |
| 393 | 393 | }; |
| 394 | 394 | |
| 395 | −void __init imx6q_pm_set_ccm_base(void __iomem *base) | |
| 396 | −{ | |
| 397 | − ccm_base = base; | |
| 398 | −} | |
| 399 | − | |
| 400 | 395 | static int __init imx6_pm_get_base(struct imx6_pm_base *base, |
| 401 | 396 | const char *compat) |
| 402 | 397 | { |
| @@ -482,8 +477,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) · 79 unmodified lines | ||
| 482 | 477 | |
| 483 | 478 | /* |
| 484 | 479 | * ccm physical address is not used by asm code currently, |
| 485 | − * so get ccm virtual address directly, as we already have | |
| 486 | − * it from ccm driver. | |
| 480 | + * so get ccm virtual address directly. | |
| 487 | 481 | */ |
| 488 | 482 | pm_info->ccm_base.vbase = ccm_base; |
| 489 | 483 | |
| @@ -568,7 +562,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata · 78 unmodified lines | ||
| 568 | 562 | |
| 569 | 563 | /* |
| 570 | 564 | * This is for SW workaround step #1 of ERR007265, see comments |
| 571 | − * in imx6q_set_lpm for details of this errata. | |
| 565 | + * in imx6_set_lpm for details of this errata. | |
| 572 | 566 | * Force IOMUXC irq pending, so that the interrupt to GPC can be |
| 573 | 567 | * used to deassert dsm_request signal when the signal gets |
| 574 | 568 | * asserted unexpectedly. |
| @@ -579,6 +573,24 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata · 4 unmodified lines | ||
| 579 | 573 | IMX6Q_GPR1_GINT); |
| 580 | 574 | } |
| 581 | 575 | |
| 576 | +void __init imx6_pm_ccm_init(const char *ccm_compat) | |
| 577 | +{ | |
| 578 | + struct device_node *np; | |
| 579 | + u32 val; | |
| 580 | + | |
| 581 | + np = of_find_compatible_node(NULL, NULL, ccm_compat); | |
| 582 | + ccm_base = of_iomap(np, 0); | |
| 583 | + BUG_ON(!ccm_base); | |
| 584 | + | |
| 585 | + /* | |
| 586 | + * Initialize CCM_CLPCR_LPM into RUN mode to avoid ARM core | |
| 587 | + * clock being shut down unexpectedly by WAIT mode. | |
| 588 | + */ | |
| 589 | + val = readl_relaxed(ccm_base + CLPCR); | |
| 590 | + val &= ~BM_CLPCR_LPM; | |
| 591 | + writel_relaxed(val, ccm_base + CLPCR); | |
| 592 | +} | |
| 593 | + | |
| 582 | 594 | void __init imx6q_pm_init(void) |
| 583 | 595 | { |
| 584 | 596 | imx6_pm_common_init(&imx6q_pm_data); |
| @@ -0,0 +1,139 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. | |
| 3 | + */ | |
| 4 | +/* | |
| 5 | + * The code contained herein is licensed under the GNU General Public | |
| 6 | + * License. You may obtain a copy of the GNU General Public License | |
| 7 | + * Version 2 or later at the following locations: | |
| 8 | + * | |
| 9 | + * http://www.opensource.org/licenses/gpl-license.html | |
| 10 | + * http://www.gnu.org/copyleft/gpl.html | |
| 11 | + */ | |
| 12 | + | |
| 13 | +#include <linux/linkage.h> | |
| 14 | + | |
| 15 | +#define M4IF_MCR0_OFFSET (0x008C) | |
| 16 | +#define M4IF_MCR0_FDVFS (0x1 << 11) | |
| 17 | +#define M4IF_MCR0_FDVACK (0x1 << 27) | |
| 18 | + | |
| 19 | + .align 3 | |
| 20 | + | |
| 21 | +/* | |
| 22 | + * ==================== low level suspend ==================== | |
| 23 | + * | |
| 24 | + * On entry | |
| 25 | + * r0: pm_info structure address; | |
| 26 | + * | |
| 27 | + * suspend ocram space layout: | |
| 28 | + * ======================== high address ====================== | |
| 29 | + * . | |
| 30 | + * . | |
| 31 | + * . | |
| 32 | + * ^ | |
| 33 | + * ^ | |
| 34 | + * ^ | |
| 35 | + * imx53_suspend code | |
| 36 | + * PM_INFO structure(imx53_suspend_info) | |
| 37 | + * ======================== low address ======================= | |
| 38 | + */ | |
| 39 | + | |
| 40 | +/* Offsets of members of struct imx53_suspend_info */ | |
| 41 | +#define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 | |
| 42 | +#define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 | |
| 43 | +#define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 | |
| 44 | +#define SUSPEND_INFO_MX53_IO_STATE_OFFSET 0xc | |
| 45 | + | |
| 46 | +ENTRY(imx53_suspend) | |
| 47 | + stmfd sp!, {r4,r5,r6,r7} | |
| 48 | + | |
| 49 | + /* Save pad config */ | |
| 50 | + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] | |
| 51 | + cmp r1, #0 | |
| 52 | + beq skip_pad_conf_1 | |
| 53 | + | |
| 54 | + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET | |
| 55 | + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] | |
| 56 | + | |
| 57 | +1: | |
| 58 | + ldr r5, [r2], #12 /* IOMUXC register offset */ | |
| 59 | + ldr r6, [r3, r5] /* current value */ | |
| 60 | + str r6, [r2], #4 /* save area */ | |
| 61 | + subs r1, r1, #1 | |
| 62 | + bne 1b | |
| 63 | + | |
| 64 | +skip_pad_conf_1: | |
| 65 | + /* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */ | |
| 66 | + ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] | |
| 67 | + ldr r2,[r1, #M4IF_MCR0_OFFSET] | |
| 68 | + orr r2, r2, #M4IF_MCR0_FDVFS | |
| 69 | + str r2,[r1, #M4IF_MCR0_OFFSET] | |
| 70 | + | |
| 71 | + /* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */ | |
| 72 | +wait_sr_ack: | |
| 73 | + ldr r2,[r1, #M4IF_MCR0_OFFSET] | |
| 74 | + ands r2, r2, #M4IF_MCR0_FDVACK | |
| 75 | + beq wait_sr_ack | |
| 76 | + | |
| 77 | + /* Set pad config */ | |
| 78 | + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] | |
| 79 | + cmp r1, #0 | |
| 80 | + beq skip_pad_conf_2 | |
| 81 | + | |
| 82 | + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET | |
| 83 | + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] | |
| 84 | + | |
| 85 | +2: | |
| 86 | + ldr r5, [r2], #4 /* IOMUXC register offset */ | |
| 87 | + ldr r6, [r2], #4 /* clear */ | |
| 88 | + ldr r7, [r3, r5] | |
| 89 | + bic r7, r7, r6 | |
| 90 | + ldr r6, [r2], #8 /* set */ | |
| 91 | + orr r7, r7, r6 | |
| 92 | + str r7, [r3, r5] | |
| 93 | + subs r1, r1, #1 | |
| 94 | + bne 2b | |
| 95 | + | |
| 96 | +skip_pad_conf_2: | |
| 97 | + /* Zzz, enter stop mode */ | |
| 98 | + wfi | |
| 99 | + nop | |
| 100 | + nop | |
| 101 | + nop | |
| 102 | + nop | |
| 103 | + | |
| 104 | + /* Restore pad config */ | |
| 105 | + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] | |
| 106 | + cmp r1, #0 | |
| 107 | + beq skip_pad_conf_3 | |
| 108 | + | |
| 109 | + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET | |
| 110 | + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] | |
| 111 | + | |
| 112 | +3: | |
| 113 | + ldr r5, [r2], #12 /* IOMUXC register offset */ | |
| 114 | + ldr r6, [r2], #4 /* saved value */ | |
| 115 | + str r6, [r3, r5] | |
| 116 | + subs r1, r1, #1 | |
| 117 | + bne 3b | |
| 118 | + | |
| 119 | +skip_pad_conf_3: | |
| 120 | + /* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */ | |
| 121 | + ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] | |
| 122 | + ldr r2,[r1, #M4IF_MCR0_OFFSET] | |
| 123 | + bic r2, r2, #M4IF_MCR0_FDVFS | |
| 124 | + str r2,[r1, #M4IF_MCR0_OFFSET] | |
| 125 | + | |
| 126 | + /* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */ | |
| 127 | +wait_ar_ack: | |
| 128 | + ldr r2,[r1, #M4IF_MCR0_OFFSET] | |
| 129 | + ands r2, r2, #M4IF_MCR0_FDVACK | |
| 130 | + bne wait_ar_ack | |
| 131 | + | |
| 132 | + /* Restore registers */ | |
| 133 | + ldmfd sp!, {r4,r5,r6,r7} | |
| 134 | + mov pc, lr | |
| 135 | + | |
| 136 | +ENDPROC(imx53_suspend) | |
| 137 | + | |
| 138 | +ENTRY(imx53_suspend_sz) | |
| 139 | + .word . - imx53_suspend | |
| @@ -1,385 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * linux/arch/arm/plat-mxc/time.c | |
| 3 | − * | |
| 4 | − * Copyright (C) 2000-2001 Deep Blue Solutions | |
| 5 | − * Copyright (C) 2002 Shane Nay (shane@minirl.com) | |
| 6 | − * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) | |
| 7 | − * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) | |
| 8 | − * | |
| 9 | − * This program is free software; you can redistribute it and/or | |
| 10 | − * modify it under the terms of the GNU General Public License | |
| 11 | − * as published by the Free Software Foundation; either version 2 | |
| 12 | − * of the License, or (at your option) any later version. | |
| 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 | − * You should have received a copy of the GNU General Public License | |
| 19 | − * along with this program; if not, write to the Free Software | |
| 20 | − * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 21 | − * MA 02110-1301, USA. | |
| 22 | − */ | |
| 23 | − | |
| 24 | −#include <linux/interrupt.h> | |
| 25 | −#include <linux/irq.h> | |
| 26 | −#include <linux/clockchips.h> | |
| 27 | −#include <linux/clk.h> | |
| 28 | −#include <linux/delay.h> | |
| 29 | −#include <linux/err.h> | |
| 30 | −#include <linux/sched_clock.h> | |
| 31 | −#include <linux/of.h> | |
| 32 | −#include <linux/of_address.h> | |
| 33 | −#include <linux/of_irq.h> | |
| 34 | − | |
| 35 | −#include <asm/mach/time.h> | |
| 36 | − | |
| 37 | −#include "common.h" | |
| 38 | −#include "hardware.h" | |
| 39 | − | |
| 40 | −/* | |
| 41 | − * There are 2 versions of the timer hardware on Freescale MXC hardware. | |
| 42 | − * Version 1: MX1/MXL, MX21, MX27. | |
| 43 | − * Version 2: MX25, MX31, MX35, MX37, MX51 | |
| 44 | − */ | |
| 45 | − | |
| 46 | −/* defines common for all i.MX */ | |
| 47 | −#define MXC_TCTL 0x00 | |
| 48 | −#define MXC_TCTL_TEN (1 << 0) /* Enable module */ | |
| 49 | −#define MXC_TPRER 0x04 | |
| 50 | − | |
| 51 | −/* MX1, MX21, MX27 */ | |
| 52 | −#define MX1_2_TCTL_CLK_PCLK1 (1 << 1) | |
| 53 | −#define MX1_2_TCTL_IRQEN (1 << 4) | |
| 54 | −#define MX1_2_TCTL_FRR (1 << 8) | |
| 55 | −#define MX1_2_TCMP 0x08 | |
| 56 | −#define MX1_2_TCN 0x10 | |
| 57 | −#define MX1_2_TSTAT 0x14 | |
| 58 | − | |
| 59 | −/* MX21, MX27 */ | |
| 60 | −#define MX2_TSTAT_CAPT (1 << 1) | |
| 61 | −#define MX2_TSTAT_COMP (1 << 0) | |
| 62 | − | |
| 63 | −/* MX31, MX35, MX25, MX5, MX6 */ | |
| 64 | −#define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ | |
| 65 | −#define V2_TCTL_CLK_IPG (1 << 6) | |
| 66 | −#define V2_TCTL_CLK_PER (2 << 6) | |
| 67 | −#define V2_TCTL_CLK_OSC_DIV8 (5 << 6) | |
| 68 | −#define V2_TCTL_FRR (1 << 9) | |
| 69 | −#define V2_TCTL_24MEN (1 << 10) | |
| 70 | −#define V2_TPRER_PRE24M 12 | |
| 71 | −#define V2_IR 0x0c | |
| 72 | −#define V2_TSTAT 0x08 | |
| 73 | −#define V2_TSTAT_OF1 (1 << 0) | |
| 74 | −#define V2_TCN 0x24 | |
| 75 | −#define V2_TCMP 0x10 | |
| 76 | − | |
| 77 | −#define V2_TIMER_RATE_OSC_DIV8 3000000 | |
| 78 | − | |
| 79 | −#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) | |
| 80 | −#define timer_is_v2() (!timer_is_v1()) | |
| 81 | − | |
| 82 | −static struct clock_event_device clockevent_mxc; | |
| 83 | −static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; | |
| 84 | − | |
| 85 | −static void __iomem *timer_base; | |
| 86 | − | |
| 87 | −static inline void gpt_irq_disable(void) | |
| 88 | −{ | |
| 89 | − unsigned int tmp; | |
| 90 | − | |
| 91 | − if (timer_is_v2()) | |
| 92 | − __raw_writel(0, timer_base + V2_IR); | |
| 93 | − else { | |
| 94 | − tmp = __raw_readl(timer_base + MXC_TCTL); | |
| 95 | − __raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL); | |
| 96 | − } | |
| 97 | −} | |
| 98 | − | |
| 99 | −static inline void gpt_irq_enable(void) | |
| 100 | −{ | |
| 101 | − if (timer_is_v2()) | |
| 102 | − __raw_writel(1<<0, timer_base + V2_IR); | |
| 103 | − else { | |
| 104 | − __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, | |
| 105 | − timer_base + MXC_TCTL); | |
| 106 | − } | |
| 107 | −} | |
| 108 | − | |
| 109 | −static void gpt_irq_acknowledge(void) | |
| 110 | −{ | |
| 111 | − if (timer_is_v1()) { | |
| 112 | − if (cpu_is_mx1()) | |
| 113 | − __raw_writel(0, timer_base + MX1_2_TSTAT); | |
| 114 | − else | |
| 115 | − __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, | |
| 116 | − timer_base + MX1_2_TSTAT); | |
| 117 | − } else if (timer_is_v2()) | |
| 118 | − __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT); | |
| 119 | −} | |
| 120 | − | |
| 121 | −static void __iomem *sched_clock_reg; | |
| 122 | − | |
| 123 | −static u64 notrace mxc_read_sched_clock(void) | |
| 124 | −{ | |
| 125 | − return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; | |
| 126 | −} | |
| 127 | − | |
| 128 | −static struct delay_timer imx_delay_timer; | |
| 129 | − | |
| 130 | −static unsigned long imx_read_current_timer(void) | |
| 131 | −{ | |
| 132 | − return __raw_readl(sched_clock_reg); | |
| 133 | −} | |
| 134 | − | |
| 135 | −static int __init mxc_clocksource_init(struct clk *timer_clk) | |
| 136 | −{ | |
| 137 | − unsigned int c = clk_get_rate(timer_clk); | |
| 138 | − void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN); | |
| 139 | − | |
| 140 | − imx_delay_timer.read_current_timer = &imx_read_current_timer; | |
| 141 | − imx_delay_timer.freq = c; | |
| 142 | − register_current_timer_delay(&imx_delay_timer); | |
| 143 | − | |
| 144 | − sched_clock_reg = reg; | |
| 145 | − | |
| 146 | − sched_clock_register(mxc_read_sched_clock, 32, c); | |
| 147 | − return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, | |
| 148 | − clocksource_mmio_readl_up); | |
| 149 | −} | |
| 150 | − | |
| 151 | −/* clock event */ | |
| 152 | − | |
| 153 | −static int mx1_2_set_next_event(unsigned long evt, | |
| 154 | − struct clock_event_device *unused) | |
| 155 | −{ | |
| 156 | − unsigned long tcmp; | |
| 157 | − | |
| 158 | − tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt; | |
| 159 | − | |
| 160 | − __raw_writel(tcmp, timer_base + MX1_2_TCMP); | |
| 161 | − | |
| 162 | − return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ? | |
| 163 | − -ETIME : 0; | |
| 164 | −} | |
| 165 | − | |
| 166 | −static int v2_set_next_event(unsigned long evt, | |
| 167 | − struct clock_event_device *unused) | |
| 168 | −{ | |
| 169 | − unsigned long tcmp; | |
| 170 | − | |
| 171 | − tcmp = __raw_readl(timer_base + V2_TCN) + evt; | |
| 172 | − | |
| 173 | − __raw_writel(tcmp, timer_base + V2_TCMP); | |
| 174 | − | |
| 175 | − return evt < 0x7fffffff && | |
| 176 | − (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ? | |
| 177 | − -ETIME : 0; | |
| 178 | −} | |
| 179 | − | |
| 180 | −#ifdef DEBUG | |
| 181 | −static const char *clock_event_mode_label[] = { | |
| 182 | − [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC", | |
| 183 | − [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT", | |
| 184 | − [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN", | |
| 185 | − [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED", | |
| 186 | − [CLOCK_EVT_MODE_RESUME] = "CLOCK_EVT_MODE_RESUME", | |
| 187 | −}; | |
| 188 | −#endif /* DEBUG */ | |
| 189 | − | |
| 190 | −static void mxc_set_mode(enum clock_event_mode mode, | |
| 191 | − struct clock_event_device *evt) | |
| 192 | −{ | |
| 193 | − unsigned long flags; | |
| 194 | − | |
| 195 | − /* | |
| 196 | − * The timer interrupt generation is disabled at least | |
| 197 | − * for enough time to call mxc_set_next_event() | |
| 198 | − */ | |
| 199 | − local_irq_save(flags); | |
| 200 | − | |
| 201 | − /* Disable interrupt in GPT module */ | |
| 202 | − gpt_irq_disable(); | |
| 203 | − | |
| 204 | − if (mode != clockevent_mode) { | |
| 205 | − /* Set event time into far-far future */ | |
| 206 | − if (timer_is_v2()) | |
| 207 | − __raw_writel(__raw_readl(timer_base + V2_TCN) - 3, | |
| 208 | − timer_base + V2_TCMP); | |
| 209 | − else | |
| 210 | − __raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3, | |
| 211 | − timer_base + MX1_2_TCMP); | |
| 212 | − | |
| 213 | − /* Clear pending interrupt */ | |
| 214 | − gpt_irq_acknowledge(); | |
| 215 | − } | |
| 216 | − | |
| 217 | −#ifdef DEBUG | |
| 218 | − printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n", | |
| 219 | − clock_event_mode_label[clockevent_mode], | |
| 220 | − clock_event_mode_label[mode]); | |
| 221 | −#endif /* DEBUG */ | |
| 222 | − | |
| 223 | − /* Remember timer mode */ | |
| 224 | − clockevent_mode = mode; | |
| 225 | − local_irq_restore(flags); | |
| 226 | − | |
| 227 | − switch (mode) { | |
| 228 | − case CLOCK_EVT_MODE_PERIODIC: | |
| 229 | − printk(KERN_ERR"mxc_set_mode: Periodic mode is not " | |
| 230 | − "supported for i.MX\n"); | |
| 231 | − break; | |
| 232 | − case CLOCK_EVT_MODE_ONESHOT: | |
| 233 | − /* | |
| 234 | − * Do not put overhead of interrupt enable/disable into | |
| 235 | − * mxc_set_next_event(), the core has about 4 minutes | |
| 236 | − * to call mxc_set_next_event() or shutdown clock after | |
| 237 | − * mode switching | |
| 238 | − */ | |
| 239 | − local_irq_save(flags); | |
| 240 | − gpt_irq_enable(); | |
| 241 | − local_irq_restore(flags); | |
| 242 | − break; | |
| 243 | − case CLOCK_EVT_MODE_SHUTDOWN: | |
| 244 | − case CLOCK_EVT_MODE_UNUSED: | |
| 245 | − case CLOCK_EVT_MODE_RESUME: | |
| 246 | − /* Left event sources disabled, no more interrupts appear */ | |
| 247 | − break; | |
| 248 | − } | |
| 249 | −} | |
| 250 | − | |
| 251 | −/* | |
| 252 | − * IRQ handler for the timer | |
| 253 | − */ | |
| 254 | −static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) | |
| 255 | −{ | |
| 256 | − struct clock_event_device *evt = &clockevent_mxc; | |
| 257 | − uint32_t tstat; | |
| 258 | − | |
| 259 | − if (timer_is_v2()) | |
| 260 | − tstat = __raw_readl(timer_base + V2_TSTAT); | |
| 261 | − else | |
| 262 | − tstat = __raw_readl(timer_base + MX1_2_TSTAT); | |
| 263 | − | |
| 264 | − gpt_irq_acknowledge(); | |
| 265 | − | |
| 266 | − evt->event_handler(evt); | |
| 267 | − | |
| 268 | − return IRQ_HANDLED; | |
| 269 | −} | |
| 270 | − | |
| 271 | −static struct irqaction mxc_timer_irq = { | |
| 272 | − .name = "i.MX Timer Tick", | |
| 273 | − .flags = IRQF_TIMER | IRQF_IRQPOLL, | |
| 274 | − .handler = mxc_timer_interrupt, | |
| 275 | −}; | |
| 276 | − | |
| 277 | −static struct clock_event_device clockevent_mxc = { | |
| 278 | − .name = "mxc_timer1", | |
| 279 | − .features = CLOCK_EVT_FEAT_ONESHOT, | |
| 280 | − .set_mode = mxc_set_mode, | |
| 281 | − .set_next_event = mx1_2_set_next_event, | |
| 282 | − .rating = 200, | |
| 283 | −}; | |
| 284 | − | |
| 285 | −static int __init mxc_clockevent_init(struct clk *timer_clk) | |
| 286 | −{ | |
| 287 | − if (timer_is_v2()) | |
| 288 | − clockevent_mxc.set_next_event = v2_set_next_event; | |
| 289 | − | |
| 290 | − clockevent_mxc.cpumask = cpumask_of(0); | |
| 291 | − clockevents_config_and_register(&clockevent_mxc, | |
| 292 | − clk_get_rate(timer_clk), | |
| 293 | − 0xff, 0xfffffffe); | |
| 294 | − | |
| 295 | − return 0; | |
| 296 | −} | |
| 297 | − | |
| 298 | −static void __init _mxc_timer_init(int irq, | |
| 299 | − struct clk *clk_per, struct clk *clk_ipg) | |
| 300 | −{ | |
| 301 | − uint32_t tctl_val; | |
| 302 | − | |
| 303 | − if (IS_ERR(clk_per)) { | |
| 304 | − pr_err("i.MX timer: unable to get clk\n"); | |
| 305 | − return; | |
| 306 | − } | |
| 307 | − | |
| 308 | − if (!IS_ERR(clk_ipg)) | |
| 309 | − clk_prepare_enable(clk_ipg); | |
| 310 | − | |
| 311 | − clk_prepare_enable(clk_per); | |
| 312 | − | |
| 313 | − /* | |
| 314 | − * Initialise to a known state (all timers off, and timing reset) | |
| 315 | − */ | |
| 316 | − | |
| 317 | − __raw_writel(0, timer_base + MXC_TCTL); | |
| 318 | − __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ | |
| 319 | − | |
| 320 | − if (timer_is_v2()) { | |
| 321 | − tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; | |
| 322 | − if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) { | |
| 323 | − tctl_val |= V2_TCTL_CLK_OSC_DIV8; | |
| 324 | − if (cpu_is_imx6dl() || cpu_is_imx6sx()) { | |
| 325 | − /* 24 / 8 = 3 MHz */ | |
| 326 | − __raw_writel(7 << V2_TPRER_PRE24M, | |
| 327 | − timer_base + MXC_TPRER); | |
| 328 | − tctl_val |= V2_TCTL_24MEN; | |
| 329 | − } | |
| 330 | − } else { | |
| 331 | − tctl_val |= V2_TCTL_CLK_PER; | |
| 332 | − } | |
| 333 | − } else { | |
| 334 | − tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; | |
| 335 | − } | |
| 336 | − | |
| 337 | − __raw_writel(tctl_val, timer_base + MXC_TCTL); | |
| 338 | − | |
| 339 | − /* init and register the timer to the framework */ | |
| 340 | − mxc_clocksource_init(clk_per); | |
| 341 | − mxc_clockevent_init(clk_per); | |
| 342 | − | |
| 343 | − /* Make irqs happen */ | |
| 344 | − setup_irq(irq, &mxc_timer_irq); | |
| 345 | −} | |
| 346 | − | |
| 347 | −void __init mxc_timer_init(void __iomem *base, int irq) | |
| 348 | −{ | |
| 349 | − struct clk *clk_per = clk_get_sys("imx-gpt.0", "per"); | |
| 350 | − struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg"); | |
| 351 | − | |
| 352 | − timer_base = base; | |
| 353 | − | |
| 354 | − _mxc_timer_init(irq, clk_per, clk_ipg); | |
| 355 | −} | |
| 356 | − | |
| 357 | −static void __init mxc_timer_init_dt(struct device_node *np) | |
| 358 | −{ | |
| 359 | − struct clk *clk_per, *clk_ipg; | |
| 360 | − int irq; | |
| 361 | − | |
| 362 | − if (timer_base) | |
| 363 | − return; | |
| 364 | − | |
| 365 | − timer_base = of_iomap(np, 0); | |
| 366 | − WARN_ON(!timer_base); | |
| 367 | − irq = irq_of_parse_and_map(np, 0); | |
| 368 | − | |
| 369 | − clk_ipg = of_clk_get_by_name(np, "ipg"); | |
| 370 | − | |
| 371 | − /* Try osc_per first, and fall back to per otherwise */ | |
| 372 | − clk_per = of_clk_get_by_name(np, "osc_per"); | |
| 373 | − if (IS_ERR(clk_per)) | |
| 374 | − clk_per = of_clk_get_by_name(np, "per"); | |
| 375 | − | |
| 376 | − _mxc_timer_init(irq, clk_per, clk_ipg); | |
| 377 | −} | |
| 378 | −CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt); | |
| 379 | −CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt); | |
| 380 | −CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", mxc_timer_init_dt); | |
| 381 | −CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", mxc_timer_init_dt); | |
| 382 | −CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", mxc_timer_init_dt); | |
| 383 | −CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", mxc_timer_init_dt); | |
| 384 | −CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", mxc_timer_init_dt); | |
| 385 | −CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", mxc_timer_init_dt); | |
| @@ -0,0 +1 @@ | ||
| 1 | +obj-y += board-dt.o | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +# Empty file waiting for deletion once Makefile.boot isn't needed any more. | |
| 2 | +# Patch waits for application at | |
| 3 | +# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 . | |
| @@ -0,0 +1,22 @@ | ||
| 1 | +/* | |
| 2 | + * Device Tree board file for NXP LPC18xx/43xx | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> | |
| 5 | + * | |
| 6 | + * This file is licensed under the terms of the GNU General Public | |
| 7 | + * License version 2. This program is licensed "as is" without any | |
| 8 | + * warranty of any kind, whether express or implied. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <asm/mach/arch.h> | |
| 12 | + | |
| 13 | +static const char *const lpc18xx_43xx_compat[] __initconst = { | |
| 14 | + "nxp,lpc1850", | |
| 15 | + "nxp,lpc4350", | |
| 16 | + "nxp,lpc4370", | |
| 17 | + NULL | |
| 18 | +}; | |
| 19 | + | |
| 20 | +DT_MACHINE_START(LPC18XXDT, "NXP LPC18xx/43xx (Device Tree)") | |
| 21 | + .dt_compat = lpc18xx_43xx_compat, | |
| 22 | +MACHINE_END | |
| @@ -17,11 +17,10 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <asm/assembler.h> |
| 18 | 18 | |
| 19 | 19 | #include <mach/board-ams-delta.h> |
| 20 | − | |
| 21 | −#include <mach/irqs.h> | |
| 22 | 20 | #include <mach/ams-delta-fiq.h> |
| 23 | 21 | |
| 24 | 22 | #include "iomap.h" |
| 23 | +#include "soc.h" | |
| 25 | 24 | |
| 26 | 25 | /* |
| 27 | 26 | * GPIO related definitions, copied from arch/arm/plat-omap/gpio.c. |
| @@ -626,6 +626,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") · 625 unmodified lines | ||
| 626 | 626 | .map_io = ams_delta_map_io, |
| 627 | 627 | .init_early = omap1_init_early, |
| 628 | 628 | .init_irq = omap1_init_irq, |
| 629 | + .handle_irq = omap1_handle_irq, | |
| 629 | 630 | .init_machine = ams_delta_init, |
| 630 | 631 | .init_late = ams_delta_init_late, |
| 631 | 632 | .init_time = omap1_timer_init, |
| @@ -362,6 +362,7 @@ MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample") · 361 unmodified lines | ||
| 362 | 362 | .map_io = omap_fsample_map_io, |
| 363 | 363 | .init_early = omap1_init_early, |
| 364 | 364 | .init_irq = omap1_init_irq, |
| 365 | + .handle_irq = omap1_handle_irq, | |
| 365 | 366 | .init_machine = omap_fsample_init, |
| 366 | 367 | .init_late = omap1_init_late, |
| 367 | 368 | .init_time = omap1_timer_init, |
| @@ -82,6 +82,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") · 81 unmodified lines | ||
| 82 | 82 | .map_io = omap16xx_map_io, |
| 83 | 83 | .init_early = omap1_init_early, |
| 84 | 84 | .init_irq = omap1_init_irq, |
| 85 | + .handle_irq = omap1_handle_irq, | |
| 85 | 86 | .init_machine = omap_generic_init, |
| 86 | 87 | .init_late = omap1_init_late, |
| 87 | 88 | .init_time = omap1_timer_init, |
| @@ -426,6 +426,7 @@ MACHINE_START(OMAP_H2, "TI-H2") · 425 unmodified lines | ||
| 426 | 426 | .map_io = omap16xx_map_io, |
| 427 | 427 | .init_early = omap1_init_early, |
| 428 | 428 | .init_irq = omap1_init_irq, |
| 429 | + .handle_irq = omap1_handle_irq, | |
| 429 | 430 | .init_machine = h2_init, |
| 430 | 431 | .init_late = omap1_init_late, |
| 431 | 432 | .init_time = omap1_timer_init, |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | #include <linux/i2c/tps65010.h> |
| 18 | 18 | |
| 19 | +#include "common.h" | |
| 19 | 20 | #include "board-h3.h" |
| 20 | 21 | #include "mmc.h" |
| 21 | 22 | |
| @@ -452,6 +452,7 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") · 451 unmodified lines | ||
| 452 | 452 | .map_io = omap16xx_map_io, |
| 453 | 453 | .init_early = omap1_init_early, |
| 454 | 454 | .init_irq = omap1_init_irq, |
| 455 | + .handle_irq = omap1_handle_irq, | |
| 455 | 456 | .init_machine = h3_init, |
| 456 | 457 | .init_late = omap1_init_late, |
| 457 | 458 | .init_time = omap1_timer_init, |
| @@ -601,6 +601,7 @@ MACHINE_START(HERALD, "HTC Herald") · 600 unmodified lines | ||
| 601 | 601 | .map_io = htcherald_map_io, |
| 602 | 602 | .init_early = omap1_init_early, |
| 603 | 603 | .init_irq = omap1_init_irq, |
| 604 | + .handle_irq = omap1_handle_irq, | |
| 604 | 605 | .init_machine = htcherald_init, |
| 605 | 606 | .init_late = omap1_init_late, |
| 606 | 607 | .init_time = omap1_timer_init, |
| @@ -456,6 +456,7 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") · 455 unmodified lines | ||
| 456 | 456 | .map_io = innovator_map_io, |
| 457 | 457 | .init_early = omap1_init_early, |
| 458 | 458 | .init_irq = omap1_init_irq, |
| 459 | + .handle_irq = omap1_handle_irq, | |
| 459 | 460 | .init_machine = innovator_init, |
| 460 | 461 | .init_late = omap1_init_late, |
| 461 | 462 | .init_time = omap1_timer_init, |
| @@ -294,6 +294,7 @@ MACHINE_START(NOKIA770, "Nokia 770") · 293 unmodified lines | ||
| 294 | 294 | .map_io = omap16xx_map_io, |
| 295 | 295 | .init_early = omap1_init_early, |
| 296 | 296 | .init_irq = omap1_init_irq, |
| 297 | + .handle_irq = omap1_handle_irq, | |
| 297 | 298 | .init_machine = omap_nokia770_init, |
| 298 | 299 | .init_late = omap1_init_late, |
| 299 | 300 | .init_time = omap1_timer_init, |
| @@ -610,6 +610,7 @@ MACHINE_START(OMAP_OSK, "TI-OSK") · 609 unmodified lines | ||
| 610 | 610 | .map_io = omap16xx_map_io, |
| 611 | 611 | .init_early = omap1_init_early, |
| 612 | 612 | .init_irq = omap1_init_irq, |
| 613 | + .handle_irq = omap1_handle_irq, | |
| 613 | 614 | .init_machine = osk_init, |
| 614 | 615 | .init_late = omap1_init_late, |
| 615 | 616 | .init_time = omap1_timer_init, |
| @@ -235,6 +235,7 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") · 234 unmodified lines | ||
| 235 | 235 | .map_io = omap15xx_map_io, |
| 236 | 236 | .init_early = omap1_init_early, |
| 237 | 237 | .init_irq = omap1_init_irq, |
| 238 | + .handle_irq = omap1_handle_irq, | |
| 238 | 239 | .init_machine = omap_palmte_init, |
| 239 | 240 | .init_late = omap1_init_late, |
| 240 | 241 | .init_time = omap1_timer_init, |
| @@ -282,6 +282,7 @@ MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T") · 281 unmodified lines | ||
| 282 | 282 | .map_io = omap15xx_map_io, |
| 283 | 283 | .init_early = omap1_init_early, |
| 284 | 284 | .init_irq = omap1_init_irq, |
| 285 | + .handle_irq = omap1_handle_irq, | |
| 285 | 286 | .init_machine = omap_palmtt_init, |
| 286 | 287 | .init_late = omap1_init_late, |
| 287 | 288 | .init_time = omap1_timer_init, |
| @@ -297,6 +297,7 @@ MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71") · 296 unmodified lines | ||
| 297 | 297 | .map_io = omap15xx_map_io, |
| 298 | 298 | .init_early = omap1_init_early, |
| 299 | 299 | .init_irq = omap1_init_irq, |
| 300 | + .handle_irq = omap1_handle_irq, | |
| 300 | 301 | .init_machine = omap_palmz71_init, |
| 301 | 302 | .init_late = omap1_init_late, |
| 302 | 303 | .init_time = omap1_timer_init, |
| @@ -324,6 +324,7 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") · 323 unmodified lines | ||
| 324 | 324 | .map_io = omap_perseus2_map_io, |
| 325 | 325 | .init_early = omap1_init_early, |
| 326 | 326 | .init_irq = omap1_init_irq, |
| 327 | + .handle_irq = omap1_handle_irq, | |
| 327 | 328 | .init_machine = omap_perseus2_init, |
| 328 | 329 | .init_late = omap1_init_late, |
| 329 | 330 | .init_time = omap1_timer_init, |
| @@ -343,6 +343,7 @@ MACHINE_START(SX1, "OMAP310 based Siemens SX1") · 342 unmodified lines | ||
| 343 | 343 | .map_io = omap15xx_map_io, |
| 344 | 344 | .init_early = omap1_init_early, |
| 345 | 345 | .init_irq = omap1_init_irq, |
| 346 | + .handle_irq = omap1_handle_irq, | |
| 346 | 347 | .init_machine = omap_sx1_init, |
| 347 | 348 | .init_late = omap1_init_late, |
| 348 | 349 | .init_time = omap1_timer_init, |
| @@ -288,6 +288,7 @@ MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") · 287 unmodified lines | ||
| 288 | 288 | .map_io = omap15xx_map_io, |
| 289 | 289 | .init_early = omap1_init_early, |
| 290 | 290 | .init_irq = omap1_init_irq, |
| 291 | + .handle_irq = omap1_handle_irq, | |
| 291 | 292 | .init_machine = voiceblue_init, |
| 292 | 293 | .init_late = omap1_init_late, |
| 293 | 294 | .init_time = omap1_timer_init, |
| @@ -30,10 +30,14 @@ · 29 unmodified lines | ||
| 30 | 30 | #include <linux/i2c-omap.h> |
| 31 | 31 | #include <linux/reboot.h> |
| 32 | 32 | |
| 33 | +#include <asm/exception.h> | |
| 34 | + | |
| 33 | 35 | #include <plat/i2c.h> |
| 34 | 36 | |
| 35 | 37 | #include <mach/irqs.h> |
| 36 | 38 | |
| 39 | +#include "soc.h" | |
| 40 | + | |
| 37 | 41 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) |
| 38 | 42 | void omap7xx_map_io(void); |
| 39 | 43 | #else |
| @@ -73,6 +77,7 @@ static inline int omap_serial_wakeup_init(void) · 33 unmodified lines | ||
| 73 | 77 | |
| 74 | 78 | void omap1_init_early(void); |
| 75 | 79 | void omap1_init_irq(void); |
| 80 | +void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs); | |
| 76 | 81 | void omap1_init_late(void); |
| 77 | 82 | void omap1_restart(enum reboot_mode, const char *); |
| 78 | 83 | |
| @@ -91,8 +96,6 @@ static inline int __init omap_32k_timer_init(void) · 12 unmodified lines | ||
| 91 | 96 | } |
| 92 | 97 | #endif |
| 93 | 98 | |
| 94 | −extern u32 omap_irq_flags; | |
| 95 | − | |
| 96 | 99 | #ifdef CONFIG_ARCH_OMAP16XX |
| 97 | 100 | extern int ocpi_enable(void); |
| 98 | 101 | #else |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/omap-dma.h> |
| 29 | 29 | #include <mach/tc.h> |
| 30 | 30 | |
| 31 | −#include <mach/irqs.h> | |
| 31 | +#include "soc.h" | |
| 32 | 32 | |
| 33 | 33 | #define OMAP1_DMA_BASE (0xfffed800) |
| 34 | 34 | #define OMAP1_LOGICAL_DMA_CH_COUNT 17 |
| @@ -21,6 +21,8 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | #include <mach/irqs.h> |
| 23 | 23 | |
| 24 | +#include "soc.h" | |
| 25 | + | |
| 24 | 26 | #define OMAP1610_GPIO1_BASE 0xfffbe400 |
| 25 | 27 | #define OMAP1610_GPIO2_BASE 0xfffbec00 |
| 26 | 28 | #define OMAP1610_GPIO3_BASE 0xfffbb400 |
| @@ -21,6 +21,8 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | #include <mach/irqs.h> |
| 23 | 23 | |
| 24 | +#include "soc.h" | |
| 25 | + | |
| 24 | 26 | #define OMAP7XX_GPIO1_BASE 0xfffbc000 |
| 25 | 27 | #define OMAP7XX_GPIO2_BASE 0xfffbc800 |
| 26 | 28 | #define OMAP7XX_GPIO3_BASE 0xfffbd000 |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | #define OMAP_I2C_SIZE 0x3f |
| 29 | 29 | #define OMAP1_I2C_BASE 0xfffb3800 |
| 30 | −#define OMAP1_INT_I2C (32 + 4) | |
| 31 | 30 | |
| 32 | 31 | static const char name[] = "omap_i2c"; |
| 33 | 32 | |
| @@ -67,7 +66,7 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *pdata, · 33 unmodified lines | ||
| 67 | 66 | res[0].start = OMAP1_I2C_BASE; |
| 68 | 67 | res[0].end = res[0].start + OMAP_I2C_SIZE; |
| 69 | 68 | res[0].flags = IORESOURCE_MEM; |
| 70 | − res[1].start = OMAP1_INT_I2C; | |
| 69 | + res[1].start = INT_I2C; | |
| 71 | 70 | res[1].flags = IORESOURCE_IRQ; |
| 72 | 71 | pdev->resource = res; |
| 73 | 72 | |
| @@ -1,39 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * arch/arm/mach-omap1/include/mach/entry-macro.S | |
| 3 | − * | |
| 4 | − * Low-level IRQ helper macros for OMAP-based platforms | |
| 5 | − * | |
| 6 | − * Copyright (C) 2009 Texas Instruments | |
| 7 | − * | |
| 8 | − * This file is licensed under the terms of the GNU General Public | |
| 9 | − * License version 2. This program is licensed "as is" without any | |
| 10 | − * warranty of any kind, whether express or implied. | |
| 11 | − */ | |
| 12 | − | |
| 13 | −#include <mach/hardware.h> | |
| 14 | −#include <mach/irqs.h> | |
| 15 | − | |
| 16 | − .macro get_irqnr_preamble, base, tmp | |
| 17 | − .endm | |
| 18 | − | |
| 19 | − .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | |
| 20 | − ldr \base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE) | |
| 21 | − ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET] | |
| 22 | − ldr \tmp, [\base, #IRQ_MIR_REG_OFFSET] | |
| 23 | − mov \irqstat, #0xffffffff | |
| 24 | − bic \tmp, \irqstat, \tmp | |
| 25 | − tst \irqnr, \tmp | |
| 26 | − beq 1510f | |
| 27 | − | |
| 28 | − ldr \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET] | |
| 29 | − ldr \tmp, =omap_irq_flags @ irq flags address | |
| 30 | − ldr \tmp, [\tmp, #0] @ irq flags value | |
| 31 | − cmp \irqnr, #0 | |
| 32 | − ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET] | |
| 33 | − cmpeq \irqnr, \tmp | |
| 34 | − ldreq \base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE) | |
| 35 | − ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET] | |
| 36 | − addeqs \irqnr, \irqnr, #32 | |
| 37 | −1510: | |
| 38 | − .endm | |
| 39 | − | |
| @@ -34,84 +34,84 @@ · 33 unmodified lines | ||
| 34 | 34 | * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below |
| 35 | 35 | * |
| 36 | 36 | */ |
| 37 | −#define INT_CAMERA 1 | |
| 38 | −#define INT_FIQ 3 | |
| 39 | −#define INT_RTDX 6 | |
| 40 | −#define INT_DSP_MMU_ABORT 7 | |
| 41 | −#define INT_HOST 8 | |
| 42 | −#define INT_ABORT 9 | |
| 43 | −#define INT_BRIDGE_PRIV 13 | |
| 44 | −#define INT_GPIO_BANK1 14 | |
| 45 | −#define INT_UART3 15 | |
| 46 | −#define INT_TIMER3 16 | |
| 47 | −#define INT_DMA_CH0_6 19 | |
| 48 | −#define INT_DMA_CH1_7 20 | |
| 49 | −#define INT_DMA_CH2_8 21 | |
| 50 | −#define INT_DMA_CH3 22 | |
| 51 | −#define INT_DMA_CH4 23 | |
| 52 | −#define INT_DMA_CH5 24 | |
| 53 | −#define INT_TIMER1 26 | |
| 54 | −#define INT_WD_TIMER 27 | |
| 55 | −#define INT_BRIDGE_PUB 28 | |
| 56 | −#define INT_TIMER2 30 | |
| 57 | −#define INT_LCD_CTRL 31 | |
| 37 | +#define INT_CAMERA (NR_IRQS_LEGACY + 1) | |
| 38 | +#define INT_FIQ (NR_IRQS_LEGACY + 3) | |
| 39 | +#define INT_RTDX (NR_IRQS_LEGACY + 6) | |
| 40 | +#define INT_DSP_MMU_ABORT (NR_IRQS_LEGACY + 7) | |
| 41 | +#define INT_HOST (NR_IRQS_LEGACY + 8) | |
| 42 | +#define INT_ABORT (NR_IRQS_LEGACY + 9) | |
| 43 | +#define INT_BRIDGE_PRIV (NR_IRQS_LEGACY + 13) | |
| 44 | +#define INT_GPIO_BANK1 (NR_IRQS_LEGACY + 14) | |
| 45 | +#define INT_UART3 (NR_IRQS_LEGACY + 15) | |
| 46 | +#define INT_TIMER3 (NR_IRQS_LEGACY + 16) | |
| 47 | +#define INT_DMA_CH0_6 (NR_IRQS_LEGACY + 19) | |
| 48 | +#define INT_DMA_CH1_7 (NR_IRQS_LEGACY + 20) | |
| 49 | +#define INT_DMA_CH2_8 (NR_IRQS_LEGACY + 21) | |
| 50 | +#define INT_DMA_CH3 (NR_IRQS_LEGACY + 22) | |
| 51 | +#define INT_DMA_CH4 (NR_IRQS_LEGACY + 23) | |
| 52 | +#define INT_DMA_CH5 (NR_IRQS_LEGACY + 24) | |
| 53 | +#define INT_TIMER1 (NR_IRQS_LEGACY + 26) | |
| 54 | +#define INT_WD_TIMER (NR_IRQS_LEGACY + 27) | |
| 55 | +#define INT_BRIDGE_PUB (NR_IRQS_LEGACY + 28) | |
| 56 | +#define INT_TIMER2 (NR_IRQS_LEGACY + 30) | |
| 57 | +#define INT_LCD_CTRL (NR_IRQS_LEGACY + 31) | |
| 58 | 58 | |
| 59 | 59 | /* |
| 60 | 60 | * OMAP-1510 specific IRQ numbers for interrupt handler 1 |
| 61 | 61 | */ |
| 62 | −#define INT_1510_IH2_IRQ 0 | |
| 63 | −#define INT_1510_RES2 2 | |
| 64 | −#define INT_1510_SPI_TX 4 | |
| 65 | −#define INT_1510_SPI_RX 5 | |
| 66 | −#define INT_1510_DSP_MAILBOX1 10 | |
| 67 | −#define INT_1510_DSP_MAILBOX2 11 | |
| 68 | −#define INT_1510_RES12 12 | |
| 69 | −#define INT_1510_LB_MMU 17 | |
| 70 | −#define INT_1510_RES18 18 | |
| 71 | −#define INT_1510_LOCAL_BUS 29 | |
| 62 | +#define INT_1510_IH2_IRQ (NR_IRQS_LEGACY + 0) | |
| 63 | +#define INT_1510_RES2 (NR_IRQS_LEGACY + 2) | |
| 64 | +#define INT_1510_SPI_TX (NR_IRQS_LEGACY + 4) | |
| 65 | +#define INT_1510_SPI_RX (NR_IRQS_LEGACY + 5) | |
| 66 | +#define INT_1510_DSP_MAILBOX1 (NR_IRQS_LEGACY + 10) | |
| 67 | +#define INT_1510_DSP_MAILBOX2 (NR_IRQS_LEGACY + 11) | |
| 68 | +#define INT_1510_RES12 (NR_IRQS_LEGACY + 12) | |
| 69 | +#define INT_1510_LB_MMU (NR_IRQS_LEGACY + 17) | |
| 70 | +#define INT_1510_RES18 (NR_IRQS_LEGACY + 18) | |
| 71 | +#define INT_1510_LOCAL_BUS (NR_IRQS_LEGACY + 29) | |
| 72 | 72 | |
| 73 | 73 | /* |
| 74 | 74 | * OMAP-1610 specific IRQ numbers for interrupt handler 1 |
| 75 | 75 | */ |
| 76 | 76 | #define INT_1610_IH2_IRQ INT_1510_IH2_IRQ |
| 77 | −#define INT_1610_IH2_FIQ 2 | |
| 78 | −#define INT_1610_McBSP2_TX 4 | |
| 79 | −#define INT_1610_McBSP2_RX 5 | |
| 80 | −#define INT_1610_DSP_MAILBOX1 10 | |
| 81 | −#define INT_1610_DSP_MAILBOX2 11 | |
| 82 | −#define INT_1610_LCD_LINE 12 | |
| 83 | −#define INT_1610_GPTIMER1 17 | |
| 84 | −#define INT_1610_GPTIMER2 18 | |
| 85 | −#define INT_1610_SSR_FIFO_0 29 | |
| 77 | +#define INT_1610_IH2_FIQ (NR_IRQS_LEGACY + 2) | |
| 78 | +#define INT_1610_McBSP2_TX (NR_IRQS_LEGACY + 4) | |
| 79 | +#define INT_1610_McBSP2_RX (NR_IRQS_LEGACY + 5) | |
| 80 | +#define INT_1610_DSP_MAILBOX1 (NR_IRQS_LEGACY + 10) | |
| 81 | +#define INT_1610_DSP_MAILBOX2 (NR_IRQS_LEGACY + 11) | |
| 82 | +#define INT_1610_LCD_LINE (NR_IRQS_LEGACY + 12) | |
| 83 | +#define INT_1610_GPTIMER1 (NR_IRQS_LEGACY + 17) | |
| 84 | +#define INT_1610_GPTIMER2 (NR_IRQS_LEGACY + 18) | |
| 85 | +#define INT_1610_SSR_FIFO_0 (NR_IRQS_LEGACY + 29) | |
| 86 | 86 | |
| 87 | 87 | /* |
| 88 | 88 | * OMAP-7xx specific IRQ numbers for interrupt handler 1 |
| 89 | 89 | */ |
| 90 | −#define INT_7XX_IH2_FIQ 0 | |
| 91 | −#define INT_7XX_IH2_IRQ 1 | |
| 92 | −#define INT_7XX_USB_NON_ISO 2 | |
| 93 | −#define INT_7XX_USB_ISO 3 | |
| 94 | −#define INT_7XX_ICR 4 | |
| 95 | −#define INT_7XX_EAC 5 | |
| 96 | −#define INT_7XX_GPIO_BANK1 6 | |
| 97 | −#define INT_7XX_GPIO_BANK2 7 | |
| 98 | −#define INT_7XX_GPIO_BANK3 8 | |
| 99 | −#define INT_7XX_McBSP2TX 10 | |
| 100 | −#define INT_7XX_McBSP2RX 11 | |
| 101 | −#define INT_7XX_McBSP2RX_OVF 12 | |
| 102 | −#define INT_7XX_LCD_LINE 14 | |
| 103 | −#define INT_7XX_GSM_PROTECT 15 | |
| 104 | −#define INT_7XX_TIMER3 16 | |
| 105 | −#define INT_7XX_GPIO_BANK5 17 | |
| 106 | −#define INT_7XX_GPIO_BANK6 18 | |
| 107 | −#define INT_7XX_SPGIO_WR 29 | |
| 90 | +#define INT_7XX_IH2_FIQ (NR_IRQS_LEGACY + 0) | |
| 91 | +#define INT_7XX_IH2_IRQ (NR_IRQS_LEGACY + 1) | |
| 92 | +#define INT_7XX_USB_NON_ISO (NR_IRQS_LEGACY + 2) | |
| 93 | +#define INT_7XX_USB_ISO (NR_IRQS_LEGACY + 3) | |
| 94 | +#define INT_7XX_ICR (NR_IRQS_LEGACY + 4) | |
| 95 | +#define INT_7XX_EAC (NR_IRQS_LEGACY + 5) | |
| 96 | +#define INT_7XX_GPIO_BANK1 (NR_IRQS_LEGACY + 6) | |
| 97 | +#define INT_7XX_GPIO_BANK2 (NR_IRQS_LEGACY + 7) | |
| 98 | +#define INT_7XX_GPIO_BANK3 (NR_IRQS_LEGACY + 8) | |
| 99 | +#define INT_7XX_McBSP2TX (NR_IRQS_LEGACY + 10) | |
| 100 | +#define INT_7XX_McBSP2RX (NR_IRQS_LEGACY + 11) | |
| 101 | +#define INT_7XX_McBSP2RX_OVF (NR_IRQS_LEGACY + 12) | |
| 102 | +#define INT_7XX_LCD_LINE (NR_IRQS_LEGACY + 14) | |
| 103 | +#define INT_7XX_GSM_PROTECT (NR_IRQS_LEGACY + 15) | |
| 104 | +#define INT_7XX_TIMER3 (NR_IRQS_LEGACY + 16) | |
| 105 | +#define INT_7XX_GPIO_BANK5 (NR_IRQS_LEGACY + 17) | |
| 106 | +#define INT_7XX_GPIO_BANK6 (NR_IRQS_LEGACY + 18) | |
| 107 | +#define INT_7XX_SPGIO_WR (NR_IRQS_LEGACY + 29) | |
| 108 | 108 | |
| 109 | 109 | /* |
| 110 | 110 | * IRQ numbers for interrupt handler 2 |
| 111 | 111 | * |
| 112 | 112 | * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below |
| 113 | 113 | */ |
| 114 | −#define IH2_BASE 32 | |
| 114 | +#define IH2_BASE (NR_IRQS_LEGACY + 32) | |
| 115 | 115 | |
| 116 | 116 | #define INT_KEYBOARD (1 + IH2_BASE) |
| 117 | 117 | #define INT_uWireTX (2 + IH2_BASE) |
| @@ -255,11 +255,7 @@ · 137 unmodified lines | ||
| 255 | 255 | #endif |
| 256 | 256 | #define OMAP_FPGA_IRQ_END (OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS) |
| 257 | 257 | |
| 258 | −#define NR_IRQS OMAP_FPGA_IRQ_END | |
| 259 | − | |
| 260 | −#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) | |
| 261 | − | |
| 262 | −#include <mach/hardware.h> | |
| 258 | +#define OMAP_IRQ_BIT(irq) (1 << ((irq - NR_IRQS_LEGACY) % 32)) | |
| 263 | 259 | |
| 264 | 260 | #ifdef CONFIG_FIQ |
| 265 | 261 | #define FIQ_START 1024 |
| @@ -5,6 +5,9 @@ · 4 unmodified lines | ||
| 5 | 5 | #ifndef __ASM_ARCH_MEMORY_H |
| 6 | 6 | #define __ASM_ARCH_MEMORY_H |
| 7 | 7 | |
| 8 | +/* REVISIT: omap1 legacy drivers still rely on this */ | |
| 9 | +#include <mach/soc.h> | |
| 10 | + | |
| 8 | 11 | /* |
| 9 | 12 | * Bus address is physical address, except for OMAP-1510 Local Bus. |
| 10 | 13 | * OMAP-1510 bus address is translated into a Local Bus address if the |
| @@ -14,7 +17,6 @@ · 3 unmodified lines | ||
| 14 | 17 | * because of the strncmp(). |
| 15 | 18 | */ |
| 16 | 19 | #if defined(CONFIG_ARCH_OMAP15XX) && !defined(__ASSEMBLER__) |
| 17 | −#include <mach/soc.h> | |
| 18 | 20 | |
| 19 | 21 | /* |
| 20 | 22 | * OMAP-1510 Local Bus address offset |
| @@ -27,11 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | */ |
| 28 | 28 | #define OMAP_UART_INFO_OFS 0x3ffc |
| 29 | 29 | |
| 30 | −/* OMAP1 serial ports */ | |
| 31 | −#define OMAP1_UART1_BASE 0xfffb0000 | |
| 32 | −#define OMAP1_UART2_BASE 0xfffb0800 | |
| 33 | −#define OMAP1_UART3_BASE 0xfffb9800 | |
| 34 | − | |
| 35 | 30 | #define OMAP_PORT_SHIFT 2 |
| 36 | 31 | #define OMAP7XX_PORT_SHIFT 0 |
| 37 | 32 | |
| @@ -28,6 +28,10 @@ · 27 unmodified lines | ||
| 28 | 28 | #ifndef __ASM_ARCH_OMAP_CPU_H |
| 29 | 29 | #define __ASM_ARCH_OMAP_CPU_H |
| 30 | 30 | |
| 31 | +#include <asm/irq.h> | |
| 32 | +#include <mach/hardware.h> | |
| 33 | +#include <mach/irqs.h> | |
| 34 | + | |
| 31 | 35 | #ifndef __ASSEMBLY__ |
| 32 | 36 | |
| 33 | 37 | #include <linux/bitops.h> |
| @@ -43,6 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | #include <linux/io.h> |
| 44 | 44 | |
| 45 | 45 | #include <asm/irq.h> |
| 46 | +#include <asm/exception.h> | |
| 46 | 47 | #include <asm/mach/irq.h> |
| 47 | 48 | |
| 48 | 49 | #include "soc.h" |
| @@ -56,66 +57,41 @@ · 7 unmodified lines | ||
| 56 | 57 | |
| 57 | 58 | struct omap_irq_bank { |
| 58 | 59 | unsigned long base_reg; |
| 60 | + void __iomem *va; | |
| 59 | 61 | unsigned long trigger_map; |
| 60 | 62 | unsigned long wake_enable; |
| 61 | 63 | }; |
| 62 | 64 | |
| 63 | −u32 omap_irq_flags; | |
| 65 | +static u32 omap_l2_irq; | |
| 64 | 66 | static unsigned int irq_bank_count; |
| 65 | 67 | static struct omap_irq_bank *irq_banks; |
| 68 | +static struct irq_domain *domain; | |
| 66 | 69 | |
| 67 | −static inline void irq_bank_writel(unsigned long value, int bank, int offset) | |
| 68 | −{ | |
| 69 | − omap_writel(value, irq_banks[bank].base_reg + offset); | |
| 70 | −} | |
| 71 | − | |
| 72 | −static void omap_ack_irq(struct irq_data *d) | |
| 70 | +static inline unsigned int irq_bank_readl(int bank, int offset) | |
| 73 | 71 | { |
| 74 | − if (d->irq > 31) | |
| 75 | − omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET); | |
| 76 | − | |
| 77 | − omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET); | |
| 72 | + return readl_relaxed(irq_banks[bank].va + offset); | |
| 78 | 73 | } |
| 79 | − | |
| 80 | −static void omap_mask_irq(struct irq_data *d) | |
| 74 | +static inline void irq_bank_writel(unsigned long value, int bank, int offset) | |
| 81 | 75 | { |
| 82 | − int bank = IRQ_BANK(d->irq); | |
| 83 | − u32 l; | |
| 84 | − | |
| 85 | − l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); | |
| 86 | − l |= 1 << IRQ_BIT(d->irq); | |
| 87 | − omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); | |
| 76 | + writel_relaxed(value, irq_banks[bank].va + offset); | |
| 88 | 77 | } |
| 89 | 78 | |
| 90 | −static void omap_unmask_irq(struct irq_data *d) | |
| 79 | +static void omap_ack_irq(int irq) | |
| 91 | 80 | { |
| 92 | − int bank = IRQ_BANK(d->irq); | |
| 93 | − u32 l; | |
| 81 | + if (irq > 31) | |
| 82 | + writel_relaxed(0x1, irq_banks[1].va + IRQ_CONTROL_REG_OFFSET); | |
| 94 | 83 | |
| 95 | − l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); | |
| 96 | − l &= ~(1 << IRQ_BIT(d->irq)); | |
| 97 | − omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); | |
| 84 | + writel_relaxed(0x1, irq_banks[0].va + IRQ_CONTROL_REG_OFFSET); | |
| 98 | 85 | } |
| 99 | 86 | |
| 100 | 87 | static void omap_mask_ack_irq(struct irq_data *d) |
| 101 | 88 | { |
| 102 | − omap_mask_irq(d); | |
| 103 | − omap_ack_irq(d); | |
| 104 | −} | |
| 105 | − | |
| 106 | −static int omap_wake_irq(struct irq_data *d, unsigned int enable) | |
| 107 | −{ | |
| 108 | − int bank = IRQ_BANK(d->irq); | |
| 109 | − | |
| 110 | − if (enable) | |
| 111 | − irq_banks[bank].wake_enable |= IRQ_BIT(d->irq); | |
| 112 | − else | |
| 113 | − irq_banks[bank].wake_enable &= ~IRQ_BIT(d->irq); | |
| 89 | + struct irq_chip_type *ct = irq_data_get_chip_type(d); | |
| 114 | 90 | |
| 115 | − return 0; | |
| 91 | + ct->chip.irq_mask(d); | |
| 92 | + omap_ack_irq(d->irq); | |
| 116 | 93 | } |
| 117 | 94 | |
| 118 | − | |
| 119 | 95 | /* |
| 120 | 96 | * Allows tuning the IRQ type and priority |
| 121 | 97 | * |
| @@ -165,46 +141,105 @@ static struct omap_irq_bank omap1610_irq_banks[] = { · 43 unmodified lines | ||
| 165 | 141 | }; |
| 166 | 142 | #endif |
| 167 | 143 | |
| 168 | −static struct irq_chip omap_irq_chip = { | |
| 169 | − .name = "MPU", | |
| 170 | − .irq_ack = omap_mask_ack_irq, | |
| 171 | − .irq_mask = omap_mask_irq, | |
| 172 | − .irq_unmask = omap_unmask_irq, | |
| 173 | − .irq_set_wake = omap_wake_irq, | |
| 174 | −}; | |
| 144 | +asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs) | |
| 145 | +{ | |
| 146 | + void __iomem *l1 = irq_banks[0].va; | |
| 147 | + void __iomem *l2 = irq_banks[1].va; | |
| 148 | + u32 irqnr; | |
| 149 | + | |
| 150 | + do { | |
| 151 | + irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET); | |
| 152 | + irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff); | |
| 153 | + if (!irqnr) | |
| 154 | + break; | |
| 155 | + | |
| 156 | + irqnr = readl_relaxed(l1 + IRQ_SIR_FIQ_REG_OFFSET); | |
| 157 | + if (irqnr) | |
| 158 | + goto irq; | |
| 159 | + | |
| 160 | + irqnr = readl_relaxed(l1 + IRQ_SIR_IRQ_REG_OFFSET); | |
| 161 | + if (irqnr == omap_l2_irq) { | |
| 162 | + irqnr = readl_relaxed(l2 + IRQ_SIR_IRQ_REG_OFFSET); | |
| 163 | + if (irqnr) | |
| 164 | + irqnr += 32; | |
| 165 | + } | |
| 166 | +irq: | |
| 167 | + if (irqnr) | |
| 168 | + handle_domain_irq(domain, irqnr, regs); | |
| 169 | + else | |
| 170 | + break; | |
| 171 | + } while (irqnr); | |
| 172 | +} | |
| 173 | + | |
| 174 | +static __init void | |
| 175 | +omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) | |
| 176 | +{ | |
| 177 | + struct irq_chip_generic *gc; | |
| 178 | + struct irq_chip_type *ct; | |
| 179 | + | |
| 180 | + gc = irq_alloc_generic_chip("MPU", 1, irq_start, base, | |
| 181 | + handle_level_irq); | |
| 182 | + ct = gc->chip_types; | |
| 183 | + ct->chip.irq_ack = omap_mask_ack_irq; | |
| 184 | + ct->chip.irq_mask = irq_gc_mask_set_bit; | |
| 185 | + ct->chip.irq_unmask = irq_gc_mask_clr_bit; | |
| 186 | + ct->chip.irq_set_wake = irq_gc_set_wake; | |
| 187 | + ct->regs.mask = IRQ_MIR_REG_OFFSET; | |
| 188 | + irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, | |
| 189 | + IRQ_NOREQUEST | IRQ_NOPROBE, 0); | |
| 190 | +} | |
| 175 | 191 | |
| 176 | 192 | void __init omap1_init_irq(void) |
| 177 | 193 | { |
| 178 | − int i, j; | |
| 194 | + struct irq_chip_type *ct; | |
| 195 | + struct irq_data *d = NULL; | |
| 196 | + int i, j, irq_base; | |
| 197 | + unsigned long nr_irqs; | |
| 179 | 198 | |
| 180 | 199 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) |
| 181 | 200 | if (cpu_is_omap7xx()) { |
| 182 | − omap_irq_flags = INT_7XX_IH2_IRQ; | |
| 183 | 201 | irq_banks = omap7xx_irq_banks; |
| 184 | 202 | irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks); |
| 185 | 203 | } |
| 186 | 204 | #endif |
| 187 | 205 | #ifdef CONFIG_ARCH_OMAP15XX |
| 188 | 206 | if (cpu_is_omap1510()) { |
| 189 | − omap_irq_flags = INT_1510_IH2_IRQ; | |
| 190 | 207 | irq_banks = omap1510_irq_banks; |
| 191 | 208 | irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); |
| 192 | 209 | } |
| 193 | 210 | if (cpu_is_omap310()) { |
| 194 | − omap_irq_flags = INT_1510_IH2_IRQ; | |
| 195 | 211 | irq_banks = omap310_irq_banks; |
| 196 | 212 | irq_bank_count = ARRAY_SIZE(omap310_irq_banks); |
| 197 | 213 | } |
| 198 | 214 | #endif |
| 199 | 215 | #if defined(CONFIG_ARCH_OMAP16XX) |
| 200 | 216 | if (cpu_is_omap16xx()) { |
| 201 | − omap_irq_flags = INT_1510_IH2_IRQ; | |
| 202 | 217 | irq_banks = omap1610_irq_banks; |
| 203 | 218 | irq_bank_count = ARRAY_SIZE(omap1610_irq_banks); |
| 204 | 219 | } |
| 205 | 220 | #endif |
| 206 | − printk("Total of %i interrupts in %i interrupt banks\n", | |
| 207 | − irq_bank_count * 32, irq_bank_count); | |
| 221 | + | |
| 222 | + for (i = 0; i < irq_bank_count; i++) { | |
| 223 | + irq_banks[i].va = ioremap(irq_banks[i].base_reg, 0xff); | |
| 224 | + if (WARN_ON(!irq_banks[i].va)) | |
| 225 | + return; | |
| 226 | + } | |
| 227 | + | |
| 228 | + nr_irqs = irq_bank_count * 32; | |
| 229 | + | |
| 230 | + irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); | |
| 231 | + if (irq_base < 0) { | |
| 232 | + pr_warn("Couldn't allocate IRQ numbers\n"); | |
| 233 | + irq_base = 0; | |
| 234 | + } | |
| 235 | + omap_l2_irq = cpu_is_omap7xx() ? irq_base + 1 : irq_base; | |
| 236 | + omap_l2_irq -= NR_IRQS_LEGACY; | |
| 237 | + | |
| 238 | + domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0, | |
| 239 | + &irq_domain_simple_ops, NULL); | |
| 240 | + | |
| 241 | + pr_info("Total of %lu interrupts in %i interrupt banks\n", | |
| 242 | + nr_irqs, irq_bank_count); | |
| 208 | 243 | |
| 209 | 244 | /* Mask and clear all interrupts */ |
| 210 | 245 | for (i = 0; i < irq_bank_count; i++) { |
| @@ -227,19 +262,15 @@ void __init omap1_init_irq(void) · 16 unmodified lines | ||
| 227 | 262 | |
| 228 | 263 | irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j); |
| 229 | 264 | omap_irq_set_cfg(j, 0, 0, irq_trigger); |
| 230 | − | |
| 231 | − irq_set_chip_and_handler(j, &omap_irq_chip, | |
| 232 | − handle_level_irq); | |
| 233 | 265 | set_irq_flags(j, IRQF_VALID); |
| 234 | 266 | } |
| 267 | + omap_alloc_gc(irq_banks[i].va, irq_base + i * 32, 32); | |
| 235 | 268 | } |
| 236 | 269 | |
| 237 | 270 | /* Unmask level 2 handler */ |
| 238 | − | |
| 239 | − if (cpu_is_omap7xx()) | |
| 240 | − omap_unmask_irq(irq_get_irq_data(INT_7XX_IH2_IRQ)); | |
| 241 | − else if (cpu_is_omap15xx()) | |
| 242 | − omap_unmask_irq(irq_get_irq_data(INT_1510_IH2_IRQ)); | |
| 243 | − else if (cpu_is_omap16xx()) | |
| 244 | − omap_unmask_irq(irq_get_irq_data(INT_1610_IH2_IRQ)); | |
| 271 | + d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq)); | |
| 272 | + if (d) { | |
| 273 | + ct = irq_data_get_chip_type(d); | |
| 274 | + ct->chip.irq_unmask(d); | |
| 275 | + } | |
| 245 | 276 | } |
| @@ -36,7 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | static struct omap_mux_cfg arch_mux_cfg; |
| 37 | 37 | |
| 38 | 38 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) |
| 39 | −static struct pin_config __initdata_or_module omap7xx_pins[] = { | |
| 39 | +static struct pin_config omap7xx_pins[] = { | |
| 40 | 40 | MUX_CFG_7XX("E2_7XX_KBR0", 12, 21, 0, 20, 1, 0) |
| 41 | 41 | MUX_CFG_7XX("J7_7XX_KBR1", 12, 25, 0, 24, 1, 0) |
| 42 | 42 | MUX_CFG_7XX("E1_7XX_KBR2", 12, 29, 0, 28, 1, 0) |
| @@ -82,7 +82,7 @@ MUX_CFG_7XX("UART_7XX_2", 8, 1, 6, 0, 0, 0) · 39 unmodified lines | ||
| 82 | 82 | #endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */ |
| 83 | 83 | |
| 84 | 84 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) |
| 85 | −static struct pin_config __initdata_or_module omap1xxx_pins[] = { | |
| 85 | +static struct pin_config omap1xxx_pins[] = { | |
| 86 | 86 | /* |
| 87 | 87 | * description mux mode mux pull pull pull pu_pd pu dbg |
| 88 | 88 | * reg offset mode reg bit ena reg |
| @@ -343,7 +343,7 @@ MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0) · 254 unmodified lines | ||
| 343 | 343 | #define OMAP1XXX_PINS_SZ 0 |
| 344 | 344 | #endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */ |
| 345 | 345 | |
| 346 | −static int __init_or_module omap1_cfg_reg(const struct pin_config *cfg) | |
| 346 | +static int omap1_cfg_reg(const struct pin_config *cfg) | |
| 347 | 347 | { |
| 348 | 348 | static DEFINE_SPINLOCK(mux_spin_lock); |
| 349 | 349 | unsigned long flags; |
| @@ -469,7 +469,7 @@ int __init omap_mux_register(struct omap_mux_cfg *arch_mux_cfg) · 119 unmodified lines | ||
| 469 | 469 | /* |
| 470 | 470 | * Sets the Omap MUX and PULL_DWN registers based on the table |
| 471 | 471 | */ |
| 472 | −int __init_or_module omap_cfg_reg(const unsigned long index) | |
| 472 | +int omap_cfg_reg(const unsigned long index) | |
| 473 | 473 | { |
| 474 | 474 | struct pin_config *reg; |
| 475 | 475 | |
| @@ -62,6 +62,7 @@ · 61 unmodified lines | ||
| 62 | 62 | #include "iomap.h" |
| 63 | 63 | #include "clock.h" |
| 64 | 64 | #include "pm.h" |
| 65 | +#include "soc.h" | |
| 65 | 66 | #include "sram.h" |
| 66 | 67 | |
| 67 | 68 | static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <mach/mux.h> |
| 26 | 26 | |
| 27 | 27 | #include "pm.h" |
| 28 | +#include "soc.h" | |
| 28 | 29 | |
| 29 | 30 | static struct clk * uart1_ck; |
| 30 | 31 | static struct clk * uart2_ck; |
| @@ -27,10 +27,10 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/platform_device.h> |
| 28 | 28 | #include <linux/platform_data/dmtimer-omap.h> |
| 29 | 29 | |
| 30 | −#include <mach/irqs.h> | |
| 31 | − | |
| 32 | 30 | #include <plat/dmtimer.h> |
| 33 | 31 | |
| 32 | +#include "soc.h" | |
| 33 | + | |
| 34 | 34 | #define OMAP1610_GPTIMER1_BASE 0xfffb1400 |
| 35 | 35 | #define OMAP1610_GPTIMER2_BASE 0xfffb1c00 |
| 36 | 36 | #define OMAP1610_GPTIMER3_BASE 0xfffb2400 |
| @@ -218,13 +218,13 @@ static int _omap_device_notifier_call(struct notifier_block *nb, · 217 unmodified lines | ||
| 218 | 218 | */ |
| 219 | 219 | static int _omap_device_enable_hwmods(struct omap_device *od) |
| 220 | 220 | { |
| 221 | + int ret = 0; | |
| 221 | 222 | int i; |
| 222 | 223 | |
| 223 | 224 | for (i = 0; i < od->hwmods_cnt; i++) |
| 224 | − omap_hwmod_enable(od->hwmods[i]); | |
| 225 | + ret |= omap_hwmod_enable(od->hwmods[i]); | |
| 225 | 226 | |
| 226 | − /* XXX pass along return value here? */ | |
| 227 | − return 0; | |
| 227 | + return ret; | |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | 230 | /** |
| @@ -235,13 +235,13 @@ static int _omap_device_enable_hwmods(struct omap_device *od) · 4 unmodified lines | ||
| 235 | 235 | */ |
| 236 | 236 | static int _omap_device_idle_hwmods(struct omap_device *od) |
| 237 | 237 | { |
| 238 | + int ret = 0; | |
| 238 | 239 | int i; |
| 239 | 240 | |
| 240 | 241 | for (i = 0; i < od->hwmods_cnt; i++) |
| 241 | − omap_hwmod_idle(od->hwmods[i]); | |
| 242 | + ret |= omap_hwmod_idle(od->hwmods[i]); | |
| 242 | 243 | |
| 243 | − /* XXX pass along return value here? */ | |
| 244 | − return 0; | |
| 244 | + return ret; | |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | 247 | /* Public functions for use by core code */ |
| @@ -589,18 +589,20 @@ static int _od_runtime_suspend(struct device *dev) · 341 unmodified lines | ||
| 589 | 589 | int ret; |
| 590 | 590 | |
| 591 | 591 | ret = pm_generic_runtime_suspend(dev); |
| 592 | + if (ret) | |
| 593 | + return ret; | |
| 592 | 594 | |
| 593 | − if (!ret) | |
| 594 | − omap_device_idle(pdev); | |
| 595 | − | |
| 596 | − return ret; | |
| 595 | + return omap_device_idle(pdev); | |
| 597 | 596 | } |
| 598 | 597 | |
| 599 | 598 | static int _od_runtime_resume(struct device *dev) |
| 600 | 599 | { |
| 601 | 600 | struct platform_device *pdev = to_platform_device(dev); |
| 601 | + int ret; | |
| 602 | 602 | |
| 603 | − omap_device_enable(pdev); | |
| 603 | + ret = omap_device_enable(pdev); | |
| 604 | + if (ret) | |
| 605 | + return ret; | |
| 604 | 606 | |
| 605 | 607 | return pm_generic_runtime_resume(dev); |
| 606 | 608 | } |
| @@ -734,7 +736,8 @@ int omap_device_enable(struct platform_device *pdev) · 127 unmodified lines | ||
| 734 | 736 | |
| 735 | 737 | ret = _omap_device_enable_hwmods(od); |
| 736 | 738 | |
| 737 | − od->_state = OMAP_DEVICE_STATE_ENABLED; | |
| 739 | + if (ret == 0) | |
| 740 | + od->_state = OMAP_DEVICE_STATE_ENABLED; | |
| 738 | 741 | |
| 739 | 742 | return ret; |
| 740 | 743 | } |
| @@ -764,7 +767,8 @@ int omap_device_idle(struct platform_device *pdev) · 23 unmodified lines | ||
| 764 | 767 | |
| 765 | 768 | ret = _omap_device_idle_hwmods(od); |
| 766 | 769 | |
| 767 | − od->_state = OMAP_DEVICE_STATE_IDLE; | |
| 770 | + if (ret == 0) | |
| 771 | + od->_state = OMAP_DEVICE_STATE_IDLE; | |
| 768 | 772 | |
| 769 | 773 | return ret; |
| 770 | 774 | } |
| @@ -3318,16 +3318,17 @@ int omap_hwmod_enable(struct omap_hwmod *oh) · 3317 unmodified lines | ||
| 3318 | 3318 | */ |
| 3319 | 3319 | int omap_hwmod_idle(struct omap_hwmod *oh) |
| 3320 | 3320 | { |
| 3321 | + int r; | |
| 3321 | 3322 | unsigned long flags; |
| 3322 | 3323 | |
| 3323 | 3324 | if (!oh) |
| 3324 | 3325 | return -EINVAL; |
| 3325 | 3326 | |
| 3326 | 3327 | spin_lock_irqsave(&oh->_lock, flags); |
| 3327 | − _idle(oh); | |
| 3328 | + r = _idle(oh); | |
| 3328 | 3329 | spin_unlock_irqrestore(&oh->_lock, flags); |
| 3329 | 3330 | |
| 3330 | − return 0; | |
| 3331 | + return r; | |
| 3331 | 3332 | } |
| 3332 | 3333 | |
| 3333 | 3334 | /** |
| @@ -3340,16 +3341,17 @@ int omap_hwmod_idle(struct omap_hwmod *oh) · 6 unmodified lines | ||
| 3340 | 3341 | */ |
| 3341 | 3342 | int omap_hwmod_shutdown(struct omap_hwmod *oh) |
| 3342 | 3343 | { |
| 3344 | + int r; | |
| 3343 | 3345 | unsigned long flags; |
| 3344 | 3346 | |
| 3345 | 3347 | if (!oh) |
| 3346 | 3348 | return -EINVAL; |
| 3347 | 3349 | |
| 3348 | 3350 | spin_lock_irqsave(&oh->_lock, flags); |
| 3349 | − _shutdown(oh); | |
| 3351 | + r = _shutdown(oh); | |
| 3350 | 3352 | spin_unlock_irqrestore(&oh->_lock, flags); |
| 3351 | 3353 | |
| 3352 | − return 0; | |
| 3354 | + return r; | |
| 3353 | 3355 | } |
| 3354 | 3356 | |
| 3355 | 3357 | /* |
| @@ -109,6 +109,12 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3; · 108 unmodified lines | ||
| 109 | 109 | |
| 110 | 110 | #define DEBUG_OMAPUART_FLAGS (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET) |
| 111 | 111 | |
| 112 | +#ifdef CONFIG_OMAP_GPMC_DEBUG | |
| 113 | +#define DEBUG_OMAP_GPMC_HWMOD_FLAGS HWMOD_INIT_NO_RESET | |
| 114 | +#else | |
| 115 | +#define DEBUG_OMAP_GPMC_HWMOD_FLAGS 0 | |
| 116 | +#endif | |
| 117 | + | |
| 112 | 118 | #if defined(CONFIG_DEBUG_OMAP2UART1) |
| 113 | 119 | #undef DEBUG_OMAP2UART1_FLAGS |
| 114 | 120 | #define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS |
| @@ -762,16 +762,8 @@ struct omap_hwmod omap2xxx_gpmc_hwmod = { · 761 unmodified lines | ||
| 762 | 762 | .name = "gpmc", |
| 763 | 763 | .class = &omap2xxx_gpmc_hwmod_class, |
| 764 | 764 | .main_clk = "gpmc_fck", |
| 765 | − /* | |
| 766 | − * XXX HWMOD_INIT_NO_RESET should not be needed for this IP | |
| 767 | − * block. It is not being added due to any known bugs with | |
| 768 | − * resetting the GPMC IP block, but rather because any timings | |
| 769 | − * set by the bootloader are not being correctly programmed by | |
| 770 | − * the kernel from the board file or DT data. | |
| 771 | − * HWMOD_INIT_NO_RESET should be removed ASAP. | |
| 772 | − */ | |
| 773 | − .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | | |
| 774 | − HWMOD_NO_IDLEST), | |
| 765 | + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ | |
| 766 | + .flags = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS, | |
| 775 | 767 | .prcm = { |
| 776 | 768 | .omap2 = { |
| 777 | 769 | .prcm_reg_id = 3, |
| @@ -145,6 +145,7 @@ extern struct omap_hwmod am33xx_uart5_hwmod; · 144 unmodified lines | ||
| 145 | 145 | extern struct omap_hwmod am33xx_uart6_hwmod; |
| 146 | 146 | extern struct omap_hwmod am33xx_wd_timer1_hwmod; |
| 147 | 147 | |
| 148 | +extern struct omap_hwmod_class am33xx_emif_hwmod_class; | |
| 148 | 149 | extern struct omap_hwmod_class am33xx_l4_hwmod_class; |
| 149 | 150 | extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class; |
| 150 | 151 | extern struct omap_hwmod_class am33xx_control_hwmod_class; |
| @@ -202,6 +202,19 @@ struct omap_hwmod am33xx_prcm_hwmod = { · 201 unmodified lines | ||
| 202 | 202 | .clkdm_name = "l4_wkup_clkdm", |
| 203 | 203 | }; |
| 204 | 204 | |
| 205 | +/* | |
| 206 | + * 'emif' class | |
| 207 | + * instance(s): emif | |
| 208 | + */ | |
| 209 | +static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = { | |
| 210 | + .rev_offs = 0x0000, | |
| 211 | +}; | |
| 212 | + | |
| 213 | +struct omap_hwmod_class am33xx_emif_hwmod_class = { | |
| 214 | + .name = "emif", | |
| 215 | + .sysc = &am33xx_emif_sysc, | |
| 216 | +}; | |
| 217 | + | |
| 205 | 218 | /* |
| 206 | 219 | * 'aes0' class |
| 207 | 220 | */ |
| @@ -668,7 +681,8 @@ struct omap_hwmod am33xx_gpmc_hwmod = { · 460 unmodified lines | ||
| 668 | 681 | .name = "gpmc", |
| 669 | 682 | .class = &am33xx_gpmc_hwmod_class, |
| 670 | 683 | .clkdm_name = "l3s_clkdm", |
| 671 | − .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), | |
| 684 | + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ | |
| 685 | + .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, | |
| 672 | 686 | .main_clk = "l3s_gclk", |
| 673 | 687 | .prcm = { |
| 674 | 688 | .omap4 = { |
| @@ -34,19 +34,6 @@ · 33 unmodified lines | ||
| 34 | 34 | * IP blocks |
| 35 | 35 | */ |
| 36 | 36 | |
| 37 | −/* | |
| 38 | − * 'emif' class | |
| 39 | − * instance(s): emif | |
| 40 | − */ | |
| 41 | −static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = { | |
| 42 | − .rev_offs = 0x0000, | |
| 43 | −}; | |
| 44 | − | |
| 45 | −static struct omap_hwmod_class am33xx_emif_hwmod_class = { | |
| 46 | − .name = "emif", | |
| 47 | − .sysc = &am33xx_emif_sysc, | |
| 48 | −}; | |
| 49 | − | |
| 50 | 37 | /* emif */ |
| 51 | 38 | static struct omap_hwmod am33xx_emif_hwmod = { |
| 52 | 39 | .name = "emif", |
| @@ -2169,16 +2169,8 @@ static struct omap_hwmod omap3xxx_gpmc_hwmod = { · 2168 unmodified lines | ||
| 2169 | 2169 | .clkdm_name = "core_l3_clkdm", |
| 2170 | 2170 | .mpu_irqs = omap3xxx_gpmc_irqs, |
| 2171 | 2171 | .main_clk = "gpmc_fck", |
| 2172 | − /* | |
| 2173 | − * XXX HWMOD_INIT_NO_RESET should not be needed for this IP | |
| 2174 | − * block. It is not being added due to any known bugs with | |
| 2175 | − * resetting the GPMC IP block, but rather because any timings | |
| 2176 | − * set by the bootloader are not being correctly programmed by | |
| 2177 | − * the kernel from the board file or DT data. | |
| 2178 | − * HWMOD_INIT_NO_RESET should be removed ASAP. | |
| 2179 | − */ | |
| 2180 | − .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | | |
| 2181 | − HWMOD_NO_IDLEST), | |
| 2172 | + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ | |
| 2173 | + .flags = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS, | |
| 2182 | 2174 | }; |
| 2183 | 2175 | |
| 2184 | 2176 | /* |
| @@ -3744,29 +3736,54 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { · 1559 unmodified lines | ||
| 3744 | 3736 | /* GP-only hwmod links */ |
| 3745 | 3737 | static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = { |
| 3746 | 3738 | &omap3xxx_l4_sec__timer12, |
| 3747 | − &omap3xxx_l4_core__sham, | |
| 3748 | − &omap3xxx_l4_core__aes, | |
| 3749 | 3739 | NULL |
| 3750 | 3740 | }; |
| 3751 | 3741 | |
| 3752 | 3742 | static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = { |
| 3753 | 3743 | &omap3xxx_l4_sec__timer12, |
| 3754 | − &omap3xxx_l4_core__sham, | |
| 3755 | − &omap3xxx_l4_core__aes, | |
| 3756 | 3744 | NULL |
| 3757 | 3745 | }; |
| 3758 | 3746 | |
| 3759 | 3747 | static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = { |
| 3760 | 3748 | &omap3xxx_l4_sec__timer12, |
| 3761 | − /* | |
| 3762 | − * Apparently the SHA/MD5 and AES accelerator IP blocks are | |
| 3763 | − * only present on some AM35xx chips, and no one knows which | |
| 3764 | − * ones. See | |
| 3765 | − * http://www.spinics.net/lists/arm-kernel/msg215466.html So | |
| 3766 | − * if you need these IP blocks on an AM35xx, try uncommenting | |
| 3767 | − * the following lines. | |
| 3768 | − */ | |
| 3749 | + NULL | |
| 3750 | +}; | |
| 3751 | + | |
| 3752 | +/* crypto hwmod links */ | |
| 3753 | +static struct omap_hwmod_ocp_if *omap34xx_sham_hwmod_ocp_ifs[] __initdata = { | |
| 3754 | + &omap3xxx_l4_core__sham, | |
| 3755 | + NULL | |
| 3756 | +}; | |
| 3757 | + | |
| 3758 | +static struct omap_hwmod_ocp_if *omap34xx_aes_hwmod_ocp_ifs[] __initdata = { | |
| 3759 | + &omap3xxx_l4_core__aes, | |
| 3760 | + NULL | |
| 3761 | +}; | |
| 3762 | + | |
| 3763 | +static struct omap_hwmod_ocp_if *omap36xx_sham_hwmod_ocp_ifs[] __initdata = { | |
| 3764 | + &omap3xxx_l4_core__sham, | |
| 3765 | + NULL | |
| 3766 | +}; | |
| 3767 | + | |
| 3768 | +static struct omap_hwmod_ocp_if *omap36xx_aes_hwmod_ocp_ifs[] __initdata = { | |
| 3769 | + &omap3xxx_l4_core__aes, | |
| 3770 | + NULL | |
| 3771 | +}; | |
| 3772 | + | |
| 3773 | +/* | |
| 3774 | + * Apparently the SHA/MD5 and AES accelerator IP blocks are | |
| 3775 | + * only present on some AM35xx chips, and no one knows which | |
| 3776 | + * ones. See | |
| 3777 | + * http://www.spinics.net/lists/arm-kernel/msg215466.html So | |
| 3778 | + * if you need these IP blocks on an AM35xx, try uncommenting | |
| 3779 | + * the following lines. | |
| 3780 | + */ | |
| 3781 | +static struct omap_hwmod_ocp_if *am35xx_sham_hwmod_ocp_ifs[] __initdata = { | |
| 3769 | 3782 | /* &omap3xxx_l4_core__sham, */ |
| 3783 | + NULL | |
| 3784 | +}; | |
| 3785 | + | |
| 3786 | +static struct omap_hwmod_ocp_if *am35xx_aes_hwmod_ocp_ifs[] __initdata = { | |
| 3770 | 3787 | /* &omap3xxx_l4_core__aes, */ |
| 3771 | 3788 | NULL |
| 3772 | 3789 | }; |
| @@ -3868,10 +3885,41 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = { · 95 unmodified lines | ||
| 3868 | 3885 | NULL |
| 3869 | 3886 | }; |
| 3870 | 3887 | |
| 3888 | +/** | |
| 3889 | + * omap3xxx_hwmod_is_hs_ip_block_usable - is a security IP block accessible? | |
| 3890 | + * @bus: struct device_node * for the top-level OMAP DT data | |
| 3891 | + * @dev_name: device name used in the DT file | |
| 3892 | + * | |
| 3893 | + * Determine whether a "secure" IP block @dev_name is usable by Linux. | |
| 3894 | + * There doesn't appear to be a 100% reliable way to determine this, | |
| 3895 | + * so we rely on heuristics. If @bus is null, meaning there's no DT | |
| 3896 | + * data, then we only assume the IP block is accessible if the OMAP is | |
| 3897 | + * fused as a 'general-purpose' SoC. If however DT data is present, | |
| 3898 | + * test to see if the IP block is described in the DT data and set to | |
| 3899 | + * 'status = "okay"'. If so then we assume the ODM has configured the | |
| 3900 | + * OMAP firewalls to allow access to the IP block. | |
| 3901 | + * | |
| 3902 | + * Return: 0 if device named @dev_name is not likely to be accessible, | |
| 3903 | + * or 1 if it is likely to be accessible. | |
| 3904 | + */ | |
| 3905 | +static int __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus, | |
| 3906 | + const char *dev_name) | |
| 3907 | +{ | |
| 3908 | + if (!bus) | |
| 3909 | + return (omap_type() == OMAP2_DEVICE_TYPE_GP) ? 1 : 0; | |
| 3910 | + | |
| 3911 | + if (of_device_is_available(of_find_node_by_name(bus, dev_name))) | |
| 3912 | + return 1; | |
| 3913 | + | |
| 3914 | + return 0; | |
| 3915 | +} | |
| 3916 | + | |
| 3871 | 3917 | int __init omap3xxx_hwmod_init(void) |
| 3872 | 3918 | { |
| 3873 | 3919 | int r; |
| 3874 | − struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL; | |
| 3920 | + struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL, **h_sham = NULL; | |
| 3921 | + struct omap_hwmod_ocp_if **h_aes = NULL; | |
| 3922 | + struct device_node *bus = NULL; | |
| 3875 | 3923 | unsigned int rev; |
| 3876 | 3924 | |
| 3877 | 3925 | omap_hwmod_init(); |
| @@ -3893,13 +3941,19 @@ int __init omap3xxx_hwmod_init(void) · 15 unmodified lines | ||
| 3893 | 3941 | rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) { |
| 3894 | 3942 | h = omap34xx_hwmod_ocp_ifs; |
| 3895 | 3943 | h_gp = omap34xx_gp_hwmod_ocp_ifs; |
| 3944 | + h_sham = omap34xx_sham_hwmod_ocp_ifs; | |
| 3945 | + h_aes = omap34xx_aes_hwmod_ocp_ifs; | |
| 3896 | 3946 | } else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { |
| 3897 | 3947 | h = am35xx_hwmod_ocp_ifs; |
| 3898 | 3948 | h_gp = am35xx_gp_hwmod_ocp_ifs; |
| 3949 | + h_sham = am35xx_sham_hwmod_ocp_ifs; | |
| 3950 | + h_aes = am35xx_aes_hwmod_ocp_ifs; | |
| 3899 | 3951 | } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 || |
| 3900 | 3952 | rev == OMAP3630_REV_ES1_2) { |
| 3901 | 3953 | h = omap36xx_hwmod_ocp_ifs; |
| 3902 | 3954 | h_gp = omap36xx_gp_hwmod_ocp_ifs; |
| 3955 | + h_sham = omap36xx_sham_hwmod_ocp_ifs; | |
| 3956 | + h_aes = omap36xx_aes_hwmod_ocp_ifs; | |
| 3903 | 3957 | } else { |
| 3904 | 3958 | WARN(1, "OMAP3 hwmod family init: unknown chip type\n"); |
| 3905 | 3959 | return -EINVAL; |
| @@ -3916,6 +3970,25 @@ int __init omap3xxx_hwmod_init(void) · 10 unmodified lines | ||
| 3916 | 3970 | return r; |
| 3917 | 3971 | } |
| 3918 | 3972 | |
| 3973 | + /* | |
| 3974 | + * Register crypto hwmod links only if they are not disabled in DT. | |
| 3975 | + * If DT information is missing, enable them only for GP devices. | |
| 3976 | + */ | |
| 3977 | + | |
| 3978 | + if (of_have_populated_dt()) | |
| 3979 | + bus = of_find_node_by_name(NULL, "ocp"); | |
| 3980 | + | |
| 3981 | + if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) { | |
| 3982 | + r = omap_hwmod_register_links(h_sham); | |
| 3983 | + if (r < 0) | |
| 3984 | + return r; | |
| 3985 | + } | |
| 3986 | + | |
| 3987 | + if (h_aes && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "aes")) { | |
| 3988 | + r = omap_hwmod_register_links(h_aes); | |
| 3989 | + if (r < 0) | |
| 3990 | + return r; | |
| 3991 | + } | |
| 3919 | 3992 | |
| 3920 | 3993 | /* |
| 3921 | 3994 | * Register hwmod links specific to certain ES levels of a |
| @@ -24,6 +24,20 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | |
| 26 | 26 | /* IP blocks */ |
| 27 | +static struct omap_hwmod am43xx_emif_hwmod = { | |
| 28 | + .name = "emif", | |
| 29 | + .class = &am33xx_emif_hwmod_class, | |
| 30 | + .clkdm_name = "emif_clkdm", | |
| 31 | + .flags = HWMOD_INIT_NO_IDLE, | |
| 32 | + .main_clk = "dpll_ddr_m2_ck", | |
| 33 | + .prcm = { | |
| 34 | + .omap4 = { | |
| 35 | + .clkctrl_offs = AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET, | |
| 36 | + .modulemode = MODULEMODE_SWCTRL, | |
| 37 | + }, | |
| 38 | + }, | |
| 39 | +}; | |
| 40 | + | |
| 27 | 41 | static struct omap_hwmod am43xx_l4_hs_hwmod = { |
| 28 | 42 | .name = "l4_hs", |
| 29 | 43 | .class = &am33xx_l4_hwmod_class, |
| @@ -583,6 +597,13 @@ static struct omap_hwmod am43xx_vpfe1_hwmod = { · 553 unmodified lines | ||
| 583 | 597 | }; |
| 584 | 598 | |
| 585 | 599 | /* Interfaces */ |
| 600 | +static struct omap_hwmod_ocp_if am43xx_l3_main__emif = { | |
| 601 | + .master = &am33xx_l3_main_hwmod, | |
| 602 | + .slave = &am43xx_emif_hwmod, | |
| 603 | + .clk = "dpll_core_m4_ck", | |
| 604 | + .user = OCP_USER_MPU | OCP_USER_SDMA, | |
| 605 | +}; | |
| 606 | + | |
| 586 | 607 | static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = { |
| 587 | 608 | .master = &am33xx_l3_main_hwmod, |
| 588 | 609 | .slave = &am43xx_l4_hs_hwmod, |
| @@ -918,6 +939,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { · 329 unmodified lines | ||
| 918 | 939 | &am33xx_l3_main__l3_instr, |
| 919 | 940 | &am33xx_l3_main__gfx, |
| 920 | 941 | &am33xx_l3_s__l3_main, |
| 942 | + &am43xx_l3_main__emif, | |
| 921 | 943 | &am33xx_pruss__l3_main, |
| 922 | 944 | &am43xx_wkup_m3__l4_wkup, |
| 923 | 945 | &am33xx_gfx__l3_main, |
| @@ -1188,15 +1188,8 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = { · 1187 unmodified lines | ||
| 1188 | 1188 | .name = "gpmc", |
| 1189 | 1189 | .class = &omap44xx_gpmc_hwmod_class, |
| 1190 | 1190 | .clkdm_name = "l3_2_clkdm", |
| 1191 | − /* | |
| 1192 | − * XXX HWMOD_INIT_NO_RESET should not be needed for this IP | |
| 1193 | − * block. It is not being added due to any known bugs with | |
| 1194 | − * resetting the GPMC IP block, but rather because any timings | |
| 1195 | − * set by the bootloader are not being correctly programmed by | |
| 1196 | − * the kernel from the board file or DT data. | |
| 1197 | − * HWMOD_INIT_NO_RESET should be removed ASAP. | |
| 1198 | − */ | |
| 1199 | − .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, | |
| 1191 | + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ | |
| 1192 | + .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, | |
| 1200 | 1193 | .prcm = { |
| 1201 | 1194 | .omap4 = { |
| 1202 | 1195 | .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET, |
| @@ -843,8 +843,8 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = { · 842 unmodified lines | ||
| 843 | 843 | .name = "gpmc", |
| 844 | 844 | .class = &dra7xx_gpmc_hwmod_class, |
| 845 | 845 | .clkdm_name = "l3main1_clkdm", |
| 846 | − .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | | |
| 847 | − HWMOD_SWSUP_SIDLE), | |
| 846 | + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ | |
| 847 | + .flags = HWMOD_SWSUP_SIDLE | DEBUG_OMAP_GPMC_HWMOD_FLAGS, | |
| 848 | 848 | .main_clk = "l3_iclk_div", |
| 849 | 849 | .prcm = { |
| 850 | 850 | .omap4 = { |
| @@ -478,6 +478,8 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = { · 477 unmodified lines | ||
| 478 | 478 | .clkdm_name = "alwon_l3s_clkdm", |
| 479 | 479 | .class = &dm81xx_gpmc_hwmod_class, |
| 480 | 480 | .main_clk = "sysclk6_ck", |
| 481 | + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ | |
| 482 | + .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, | |
| 481 | 483 | .prcm = { |
| 482 | 484 | .omap4 = { |
| 483 | 485 | .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL, |
| @@ -146,4 +146,6 @@ · 145 unmodified lines | ||
| 146 | 146 | #define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET 0x04a0 |
| 147 | 147 | #define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET 0x0068 |
| 148 | 148 | #define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET 0x0070 |
| 149 | +#define AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET 0x0720 | |
| 150 | + | |
| 149 | 151 | #endif |
| @@ -3,16 +3,15 @@ · 2 unmodified lines | ||
| 3 | 3 | # |
| 4 | 4 | |
| 5 | 5 | # Common support (must be linked before board specific support) |
| 6 | −obj-y += clock.o devices.o generic.o irq.o \ | |
| 7 | − reset.o | |
| 6 | +obj-y += devices.o generic.o irq.o reset.o | |
| 8 | 7 | obj-$(CONFIG_PM) += pm.o sleep.o standby.o |
| 9 | 8 | |
| 10 | 9 | # Generic drivers that other drivers may depend upon |
| 11 | 10 | |
| 12 | 11 | # SoC-specific code |
| 13 | −obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa25x.o | |
| 14 | −obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa27x.o | |
| 15 | −obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o clock-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o | |
| 12 | +obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o | |
| 13 | +obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o | |
| 14 | +obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o | |
| 16 | 15 | obj-$(CONFIG_CPU_PXA300) += pxa300.o |
| 17 | 16 | obj-$(CONFIG_CPU_PXA320) += pxa320.o |
| 18 | 17 | obj-$(CONFIG_CPU_PXA930) += pxa930.o |
| @@ -1,55 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * linux/arch/arm/mach-pxa/clock-pxa2xx.c | |
| 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/module.h> | |
| 10 | −#include <linux/kernel.h> | |
| 11 | −#include <linux/init.h> | |
| 12 | −#include <linux/io.h> | |
| 13 | −#include <linux/syscore_ops.h> | |
| 14 | − | |
| 15 | −#include <mach/pxa2xx-regs.h> | |
| 16 | − | |
| 17 | −#include "clock.h" | |
| 18 | − | |
| 19 | −void clk_pxa2xx_cken_enable(struct clk *clk) | |
| 20 | −{ | |
| 21 | − CKEN |= 1 << clk->cken; | |
| 22 | −} | |
| 23 | − | |
| 24 | −void clk_pxa2xx_cken_disable(struct clk *clk) | |
| 25 | −{ | |
| 26 | − CKEN &= ~(1 << clk->cken); | |
| 27 | −} | |
| 28 | − | |
| 29 | −const struct clkops clk_pxa2xx_cken_ops = { | |
| 30 | − .enable = clk_pxa2xx_cken_enable, | |
| 31 | − .disable = clk_pxa2xx_cken_disable, | |
| 32 | −}; | |
| 33 | − | |
| 34 | −#ifdef CONFIG_PM | |
| 35 | −static uint32_t saved_cken; | |
| 36 | − | |
| 37 | −static int pxa2xx_clock_suspend(void) | |
| 38 | −{ | |
| 39 | − saved_cken = CKEN; | |
| 40 | − return 0; | |
| 41 | −} | |
| 42 | − | |
| 43 | −static void pxa2xx_clock_resume(void) | |
| 44 | −{ | |
| 45 | − CKEN = saved_cken; | |
| 46 | −} | |
| 47 | −#else | |
| 48 | −#define pxa2xx_clock_suspend NULL | |
| 49 | −#define pxa2xx_clock_resume NULL | |
| 50 | −#endif | |
| 51 | − | |
| 52 | −struct syscore_ops pxa2xx_clock_syscore_ops = { | |
| 53 | − .suspend = pxa2xx_clock_suspend, | |
| 54 | − .resume = pxa2xx_clock_resume, | |
| 55 | −}; | |
| @@ -1,212 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * linux/arch/arm/mach-pxa/clock-pxa3xx.c | |
| 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/module.h> | |
| 10 | −#include <linux/kernel.h> | |
| 11 | −#include <linux/init.h> | |
| 12 | −#include <linux/io.h> | |
| 13 | −#include <linux/syscore_ops.h> | |
| 14 | − | |
| 15 | −#include <mach/smemc.h> | |
| 16 | −#include <mach/pxa3xx-regs.h> | |
| 17 | − | |
| 18 | −#include "clock.h" | |
| 19 | − | |
| 20 | −/* Crystal clock: 13MHz */ | |
| 21 | −#define BASE_CLK 13000000 | |
| 22 | − | |
| 23 | −/* Ring Oscillator Clock: 60MHz */ | |
| 24 | −#define RO_CLK 60000000 | |
| 25 | − | |
| 26 | −#define ACCR_D0CS (1 << 26) | |
| 27 | −#define ACCR_PCCE (1 << 11) | |
| 28 | − | |
| 29 | −/* crystal frequency to HSIO bus frequency multiplier (HSS) */ | |
| 30 | −static unsigned char hss_mult[4] = { 8, 12, 16, 24 }; | |
| 31 | − | |
| 32 | −/* | |
| 33 | − * Get the clock frequency as reflected by CCSR and the turbo flag. | |
| 34 | − * We assume these values have been applied via a fcs. | |
| 35 | − * If info is not 0 we also display the current settings. | |
| 36 | − */ | |
| 37 | −unsigned int pxa3xx_get_clk_frequency_khz(int info) | |
| 38 | −{ | |
| 39 | − unsigned long acsr, xclkcfg; | |
| 40 | − unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS; | |
| 41 | − | |
| 42 | − /* Read XCLKCFG register turbo bit */ | |
| 43 | − __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg)); | |
| 44 | − t = xclkcfg & 0x1; | |
| 45 | − | |
| 46 | − acsr = ACSR; | |
| 47 | − | |
| 48 | − xl = acsr & 0x1f; | |
| 49 | − xn = (acsr >> 8) & 0x7; | |
| 50 | − hss = (acsr >> 14) & 0x3; | |
| 51 | − | |
| 52 | − XL = xl * BASE_CLK; | |
| 53 | − XN = xn * XL; | |
| 54 | − | |
| 55 | − ro = acsr & ACCR_D0CS; | |
| 56 | − | |
| 57 | − CLK = (ro) ? RO_CLK : ((t) ? XN : XL); | |
| 58 | − HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK; | |
| 59 | − | |
| 60 | − if (info) { | |
| 61 | − pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n", | |
| 62 | − RO_CLK / 1000000, (RO_CLK % 1000000) / 10000, | |
| 63 | − (ro) ? "" : "in"); | |
| 64 | − pr_info("Run Mode clock: %d.%02dMHz (*%d)\n", | |
| 65 | − XL / 1000000, (XL % 1000000) / 10000, xl); | |
| 66 | − pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n", | |
| 67 | − XN / 1000000, (XN % 1000000) / 10000, xn, | |
| 68 | − (t) ? "" : "in"); | |
| 69 | − pr_info("HSIO bus clock: %d.%02dMHz\n", | |
| 70 | − HSS / 1000000, (HSS % 1000000) / 10000); | |
| 71 | − } | |
| 72 | − | |
| 73 | − return CLK / 1000; | |
| 74 | −} | |
| 75 | − | |
| 76 | −/* | |
| 77 | − * Return the current AC97 clock frequency. | |
| 78 | − */ | |
| 79 | −static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk) | |
| 80 | −{ | |
| 81 | − unsigned long rate = 312000000; | |
| 82 | − unsigned long ac97_div; | |
| 83 | − | |
| 84 | − ac97_div = AC97_DIV; | |
| 85 | − | |
| 86 | − /* This may loose precision for some rates but won't for the | |
| 87 | − * standard 24.576MHz. | |
| 88 | − */ | |
| 89 | − rate /= (ac97_div >> 12) & 0x7fff; | |
| 90 | − rate *= (ac97_div & 0xfff); | |
| 91 | − | |
| 92 | − return rate; | |
| 93 | −} | |
| 94 | − | |
| 95 | −/* | |
| 96 | − * Return the current HSIO bus clock frequency | |
| 97 | − */ | |
| 98 | −static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) | |
| 99 | −{ | |
| 100 | − unsigned long acsr; | |
| 101 | − unsigned int hss, hsio_clk; | |
| 102 | − | |
| 103 | − acsr = ACSR; | |
| 104 | − | |
| 105 | − hss = (acsr >> 14) & 0x3; | |
| 106 | − hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK; | |
| 107 | − | |
| 108 | − return hsio_clk; | |
| 109 | −} | |
| 110 | − | |
| 111 | −/* crystal frequency to static memory controller multiplier (SMCFS) */ | |
| 112 | −static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; | |
| 113 | −static unsigned int df_clkdiv[4] = { 1, 2, 4, 1 }; | |
| 114 | − | |
| 115 | −static unsigned long clk_pxa3xx_smemc_getrate(struct clk *clk) | |
| 116 | −{ | |
| 117 | − unsigned long acsr = ACSR; | |
| 118 | − unsigned long memclkcfg = __raw_readl(MEMCLKCFG); | |
| 119 | − | |
| 120 | − return BASE_CLK * smcfs_mult[(acsr >> 23) & 0x7] / | |
| 121 | − df_clkdiv[(memclkcfg >> 16) & 0x3]; | |
| 122 | −} | |
| 123 | − | |
| 124 | −void clk_pxa3xx_cken_enable(struct clk *clk) | |
| 125 | −{ | |
| 126 | − unsigned long mask = 1ul << (clk->cken & 0x1f); | |
| 127 | − | |
| 128 | − if (clk->cken < 32) | |
| 129 | − CKENA |= mask; | |
| 130 | − else if (clk->cken < 64) | |
| 131 | − CKENB |= mask; | |
| 132 | − else | |
| 133 | − CKENC |= mask; | |
| 134 | −} | |
| 135 | − | |
| 136 | −void clk_pxa3xx_cken_disable(struct clk *clk) | |
| 137 | −{ | |
| 138 | − unsigned long mask = 1ul << (clk->cken & 0x1f); | |
| 139 | − | |
| 140 | − if (clk->cken < 32) | |
| 141 | − CKENA &= ~mask; | |
| 142 | − else if (clk->cken < 64) | |
| 143 | − CKENB &= ~mask; | |
| 144 | − else | |
| 145 | − CKENC &= ~mask; | |
| 146 | −} | |
| 147 | − | |
| 148 | −const struct clkops clk_pxa3xx_cken_ops = { | |
| 149 | − .enable = clk_pxa3xx_cken_enable, | |
| 150 | − .disable = clk_pxa3xx_cken_disable, | |
| 151 | −}; | |
| 152 | − | |
| 153 | −const struct clkops clk_pxa3xx_hsio_ops = { | |
| 154 | − .enable = clk_pxa3xx_cken_enable, | |
| 155 | − .disable = clk_pxa3xx_cken_disable, | |
| 156 | − .getrate = clk_pxa3xx_hsio_getrate, | |
| 157 | −}; | |
| 158 | − | |
| 159 | −const struct clkops clk_pxa3xx_ac97_ops = { | |
| 160 | − .enable = clk_pxa3xx_cken_enable, | |
| 161 | − .disable = clk_pxa3xx_cken_disable, | |
| 162 | − .getrate = clk_pxa3xx_ac97_getrate, | |
| 163 | −}; | |
| 164 | − | |
| 165 | −const struct clkops clk_pxa3xx_smemc_ops = { | |
| 166 | − .enable = clk_pxa3xx_cken_enable, | |
| 167 | − .disable = clk_pxa3xx_cken_disable, | |
| 168 | − .getrate = clk_pxa3xx_smemc_getrate, | |
| 169 | −}; | |
| 170 | − | |
| 171 | −static void clk_pout_enable(struct clk *clk) | |
| 172 | −{ | |
| 173 | − OSCC |= OSCC_PEN; | |
| 174 | −} | |
| 175 | − | |
| 176 | −static void clk_pout_disable(struct clk *clk) | |
| 177 | −{ | |
| 178 | − OSCC &= ~OSCC_PEN; | |
| 179 | −} | |
| 180 | − | |
| 181 | −const struct clkops clk_pxa3xx_pout_ops = { | |
| 182 | − .enable = clk_pout_enable, | |
| 183 | − .disable = clk_pout_disable, | |
| 184 | −}; | |
| 185 | − | |
| 186 | −#ifdef CONFIG_PM | |
| 187 | −static uint32_t cken[2]; | |
| 188 | −static uint32_t accr; | |
| 189 | − | |
| 190 | −static int pxa3xx_clock_suspend(void) | |
| 191 | −{ | |
| 192 | − cken[0] = CKENA; | |
| 193 | − cken[1] = CKENB; | |
| 194 | − accr = ACCR; | |
| 195 | − return 0; | |
| 196 | −} | |
| 197 | − | |
| 198 | −static void pxa3xx_clock_resume(void) | |
| 199 | −{ | |
| 200 | − ACCR = accr; | |
| 201 | − CKENA = cken[0]; | |
| 202 | − CKENB = cken[1]; | |
| 203 | −} | |
| 204 | −#else | |
| 205 | −#define pxa3xx_clock_suspend NULL | |
| 206 | −#define pxa3xx_clock_resume NULL | |
| 207 | −#endif | |
| 208 | − | |
| 209 | −struct syscore_ops pxa3xx_clock_syscore_ops = { | |
| 210 | − .suspend = pxa3xx_clock_suspend, | |
| 211 | − .resume = pxa3xx_clock_resume, | |
| 212 | −}; | |
| @@ -1,86 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * linux/arch/arm/mach-sa1100/clock.c | |
| 3 | − */ | |
| 4 | −#include <linux/module.h> | |
| 5 | −#include <linux/kernel.h> | |
| 6 | −#include <linux/clk.h> | |
| 7 | −#include <linux/spinlock.h> | |
| 8 | −#include <linux/delay.h> | |
| 9 | −#include <linux/clkdev.h> | |
| 10 | − | |
| 11 | −#include "clock.h" | |
| 12 | − | |
| 13 | −static DEFINE_SPINLOCK(clocks_lock); | |
| 14 | − | |
| 15 | −int clk_enable(struct clk *clk) | |
| 16 | −{ | |
| 17 | − unsigned long flags; | |
| 18 | − | |
| 19 | − spin_lock_irqsave(&clocks_lock, flags); | |
| 20 | − if (clk->enabled++ == 0) | |
| 21 | − clk->ops->enable(clk); | |
| 22 | − spin_unlock_irqrestore(&clocks_lock, flags); | |
| 23 | − | |
| 24 | − if (clk->delay) | |
| 25 | − udelay(clk->delay); | |
| 26 | − | |
| 27 | − return 0; | |
| 28 | −} | |
| 29 | −EXPORT_SYMBOL(clk_enable); | |
| 30 | − | |
| 31 | −void clk_disable(struct clk *clk) | |
| 32 | −{ | |
| 33 | − unsigned long flags; | |
| 34 | − | |
| 35 | − WARN_ON(clk->enabled == 0); | |
| 36 | − | |
| 37 | − spin_lock_irqsave(&clocks_lock, flags); | |
| 38 | − if (--clk->enabled == 0) | |
| 39 | − clk->ops->disable(clk); | |
| 40 | − spin_unlock_irqrestore(&clocks_lock, flags); | |
| 41 | −} | |
| 42 | −EXPORT_SYMBOL(clk_disable); | |
| 43 | − | |
| 44 | −unsigned long clk_get_rate(struct clk *clk) | |
| 45 | −{ | |
| 46 | − unsigned long rate; | |
| 47 | − | |
| 48 | − rate = clk->rate; | |
| 49 | − if (clk->ops->getrate) | |
| 50 | − rate = clk->ops->getrate(clk); | |
| 51 | − | |
| 52 | − return rate; | |
| 53 | −} | |
| 54 | −EXPORT_SYMBOL(clk_get_rate); | |
| 55 | − | |
| 56 | −int clk_set_rate(struct clk *clk, unsigned long rate) | |
| 57 | −{ | |
| 58 | − unsigned long flags; | |
| 59 | − int ret = -EINVAL; | |
| 60 | − | |
| 61 | − if (clk->ops->setrate) { | |
| 62 | − spin_lock_irqsave(&clocks_lock, flags); | |
| 63 | − ret = clk->ops->setrate(clk, rate); | |
| 64 | − spin_unlock_irqrestore(&clocks_lock, flags); | |
| 65 | − } | |
| 66 | − | |
| 67 | − return ret; | |
| 68 | −} | |
| 69 | −EXPORT_SYMBOL(clk_set_rate); | |
| 70 | − | |
| 71 | −void clk_dummy_enable(struct clk *clk) | |
| 72 | −{ | |
| 73 | −} | |
| 74 | − | |
| 75 | −void clk_dummy_disable(struct clk *clk) | |
| 76 | −{ | |
| 77 | −} | |
| 78 | − | |
| 79 | −const struct clkops clk_dummy_ops = { | |
| 80 | − .enable = clk_dummy_enable, | |
| 81 | − .disable = clk_dummy_disable, | |
| 82 | −}; | |
| 83 | − | |
| 84 | −struct clk clk_dummy = { | |
| 85 | − .ops = &clk_dummy_ops, | |
| 86 | −}; | |
| @@ -1,80 +0,0 @@ | ||
| 1 | −#include <linux/clkdev.h> | |
| 2 | −#include <linux/syscore_ops.h> | |
| 3 | − | |
| 4 | −struct clkops { | |
| 5 | − void (*enable)(struct clk *); | |
| 6 | − void (*disable)(struct clk *); | |
| 7 | − unsigned long (*getrate)(struct clk *); | |
| 8 | − int (*setrate)(struct clk *, unsigned long); | |
| 9 | −}; | |
| 10 | − | |
| 11 | −struct clk { | |
| 12 | − const struct clkops *ops; | |
| 13 | − unsigned long rate; | |
| 14 | − unsigned int cken; | |
| 15 | − unsigned int delay; | |
| 16 | − unsigned int enabled; | |
| 17 | −}; | |
| 18 | − | |
| 19 | −void clk_dummy_enable(struct clk *); | |
| 20 | −void clk_dummy_disable(struct clk *); | |
| 21 | − | |
| 22 | −extern const struct clkops clk_dummy_ops; | |
| 23 | −extern struct clk clk_dummy; | |
| 24 | − | |
| 25 | −#define INIT_CLKREG(_clk,_devname,_conname) \ | |
| 26 | − { \ | |
| 27 | − .clk = _clk, \ | |
| 28 | − .dev_id = _devname, \ | |
| 29 | − .con_id = _conname, \ | |
| 30 | − } | |
| 31 | − | |
| 32 | −#define DEFINE_CK(_name, _cken, _ops) \ | |
| 33 | −struct clk clk_##_name = { \ | |
| 34 | − .ops = _ops, \ | |
| 35 | − .cken = CKEN_##_cken, \ | |
| 36 | − } | |
| 37 | − | |
| 38 | −#define DEFINE_CLK(_name, _ops, _rate, _delay) \ | |
| 39 | −struct clk clk_##_name = { \ | |
| 40 | − .ops = _ops, \ | |
| 41 | − .rate = _rate, \ | |
| 42 | − .delay = _delay, \ | |
| 43 | − } | |
| 44 | − | |
| 45 | −#define DEFINE_PXA2_CKEN(_name, _cken, _rate, _delay) \ | |
| 46 | −struct clk clk_##_name = { \ | |
| 47 | − .ops = &clk_pxa2xx_cken_ops, \ | |
| 48 | − .rate = _rate, \ | |
| 49 | − .cken = CKEN_##_cken, \ | |
| 50 | − .delay = _delay, \ | |
| 51 | − } | |
| 52 | − | |
| 53 | −extern const struct clkops clk_pxa2xx_cken_ops; | |
| 54 | − | |
| 55 | −void clk_pxa2xx_cken_enable(struct clk *clk); | |
| 56 | −void clk_pxa2xx_cken_disable(struct clk *clk); | |
| 57 | − | |
| 58 | −extern struct syscore_ops pxa2xx_clock_syscore_ops; | |
| 59 | − | |
| 60 | −#if defined(CONFIG_PXA3xx) | |
| 61 | −#define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \ | |
| 62 | −struct clk clk_##_name = { \ | |
| 63 | − .ops = &clk_pxa3xx_cken_ops, \ | |
| 64 | − .rate = _rate, \ | |
| 65 | − .cken = CKEN_##_cken, \ | |
| 66 | − .delay = _delay, \ | |
| 67 | − } | |
| 68 | − | |
| 69 | −extern const struct clkops clk_pxa3xx_cken_ops; | |
| 70 | −extern const struct clkops clk_pxa3xx_hsio_ops; | |
| 71 | −extern const struct clkops clk_pxa3xx_ac97_ops; | |
| 72 | −extern const struct clkops clk_pxa3xx_pout_ops; | |
| 73 | −extern const struct clkops clk_pxa3xx_smemc_ops; | |
| 74 | − | |
| 75 | −extern void clk_pxa3xx_cken_enable(struct clk *); | |
| 76 | −extern void clk_pxa3xx_cken_disable(struct clk *); | |
| 77 | − | |
| 78 | −extern struct syscore_ops pxa3xx_clock_syscore_ops; | |
| 79 | − | |
| 80 | −#endif | |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/clkdev.h> |
| 14 | 14 | #include <linux/kernel.h> |
| 15 | 15 | #include <linux/init.h> |
| 16 | +#include <linux/clk-provider.h> | |
| 16 | 17 | #include <linux/gpio.h> |
| 17 | 18 | #include <linux/delay.h> |
| 18 | 19 | #include <linux/platform_device.h> |
| @@ -40,7 +41,6 @@ · 21 unmodified lines | ||
| 40 | 41 | |
| 41 | 42 | #include "devices.h" |
| 42 | 43 | #include "generic.h" |
| 43 | −#include "clock.h" | |
| 44 | 44 | |
| 45 | 45 | /* Only e800 has 128MB RAM */ |
| 46 | 46 | void __init eseries_fixup(struct tag *tags, char **cmdline) |
| @@ -126,27 +126,9 @@ struct resource eseries_tmio_resources[] = { · 79 unmodified lines | ||
| 126 | 126 | }; |
| 127 | 127 | |
| 128 | 128 | /* Some e-series hardware cannot control the 32K clock */ |
| 129 | −static void clk_32k_dummy(struct clk *clk) | |
| 130 | −{ | |
| 131 | −} | |
| 132 | − | |
| 133 | −static const struct clkops clk_32k_dummy_ops = { | |
| 134 | − .enable = clk_32k_dummy, | |
| 135 | − .disable = clk_32k_dummy, | |
| 136 | −}; | |
| 137 | − | |
| 138 | −static struct clk tmio_dummy_clk = { | |
| 139 | − .ops = &clk_32k_dummy_ops, | |
| 140 | − .rate = 32768, | |
| 141 | −}; | |
| 142 | − | |
| 143 | −static struct clk_lookup eseries_clkregs[] = { | |
| 144 | − INIT_CLKREG(&tmio_dummy_clk, NULL, "CLK_CK32K"), | |
| 145 | −}; | |
| 146 | − | |
| 147 | 129 | static void __init eseries_register_clks(void) |
| 148 | 130 | { |
| 149 | − clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs)); | |
| 131 | + clk_register_fixed_rate(NULL, "CLK_CK32K", NULL, CLK_IS_ROOT, 32768); | |
| 150 | 132 | } |
| 151 | 133 | |
| 152 | 134 | #ifdef CONFIG_MACH_E330 |
| @@ -684,7 +666,7 @@ static unsigned long e750_pin_config[] __initdata = { · 531 unmodified lines | ||
| 684 | 666 | /* PC Card */ |
| 685 | 667 | GPIO8_GPIO, /* CD0 */ |
| 686 | 668 | GPIO44_GPIO, /* CD1 */ |
| 687 | − GPIO11_GPIO, /* IRQ0 */ | |
| 669 | + /* GPIO11_GPIO, IRQ0 */ | |
| 688 | 670 | GPIO6_GPIO, /* IRQ1 */ |
| 689 | 671 | GPIO27_GPIO, /* RST0 */ |
| 690 | 672 | GPIO24_GPIO, /* RST1 */ |
| @@ -779,6 +761,9 @@ static unsigned long e800_pin_config[] __initdata = { · 88 unmodified lines | ||
| 779 | 761 | GPIO29_AC97_SDATA_IN_0, |
| 780 | 762 | GPIO30_AC97_SDATA_OUT, |
| 781 | 763 | GPIO31_AC97_SYNC, |
| 764 | + | |
| 765 | + /* tc6393xb */ | |
| 766 | + GPIO11_3_6MHz, | |
| 782 | 767 | }; |
| 783 | 768 | |
| 784 | 769 | static struct w100_gen_regs e800_lcd_regs = { |
| @@ -63,6 +63,12 @@ EXPORT_SYMBOL(get_clock_tick_rate); · 62 unmodified lines | ||
| 63 | 63 | */ |
| 64 | 64 | void __init pxa_timer_init(void) |
| 65 | 65 | { |
| 66 | + if (cpu_is_pxa25x()) | |
| 67 | + pxa25x_clocks_init(); | |
| 68 | + if (cpu_is_pxa27x()) | |
| 69 | + pxa27x_clocks_init(); | |
| 70 | + if (cpu_is_pxa3xx()) | |
| 71 | + pxa3xx_clocks_init(); | |
| 66 | 72 | pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a00000), |
| 67 | 73 | get_clock_tick_rate()); |
| 68 | 74 | } |
| @@ -26,17 +26,20 @@ extern void pxa_timer_init(void); · 25 unmodified lines | ||
| 26 | 26 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) |
| 27 | 27 | |
| 28 | 28 | #define pxa25x_handle_irq icip_handle_irq |
| 29 | +extern int __init pxa25x_clocks_init(void); | |
| 29 | 30 | extern void __init pxa25x_init_irq(void); |
| 30 | 31 | extern void __init pxa25x_map_io(void); |
| 31 | 32 | extern void __init pxa26x_init_irq(void); |
| 32 | 33 | |
| 33 | 34 | #define pxa27x_handle_irq ichp_handle_irq |
| 35 | +extern int __init pxa27x_clocks_init(void); | |
| 34 | 36 | extern void __init pxa27x_dt_init_irq(void); |
| 35 | 37 | extern unsigned pxa27x_get_clk_frequency_khz(int); |
| 36 | 38 | extern void __init pxa27x_init_irq(void); |
| 37 | 39 | extern void __init pxa27x_map_io(void); |
| 38 | 40 | |
| 39 | 41 | #define pxa3xx_handle_irq ichp_handle_irq |
| 42 | +extern int __init pxa3xx_clocks_init(void); | |
| 40 | 43 | extern void __init pxa3xx_dt_init_irq(void); |
| 41 | 44 | extern void __init pxa3xx_init_irq(void); |
| 42 | 45 | extern void __init pxa3xx_map_io(void); |
| @@ -138,7 +138,7 @@ static int pxa_irq_map(struct irq_domain *h, unsigned int virq, · 137 unmodified lines | ||
| 138 | 138 | return 0; |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | −static struct irq_domain_ops pxa_irq_ops = { | |
| 141 | +static const struct irq_domain_ops pxa_irq_ops = { | |
| 142 | 142 | .map = pxa_irq_map, |
| 143 | 143 | .xlate = irq_domain_xlate_onecell, |
| 144 | 144 | }; |
| @@ -58,7 +58,6 @@ · 57 unmodified lines | ||
| 58 | 58 | #include <mach/smemc.h> |
| 59 | 59 | |
| 60 | 60 | #include "generic.h" |
| 61 | −#include "clock.h" | |
| 62 | 61 | #include "devices.h" |
| 63 | 62 | |
| 64 | 63 | static unsigned long lubbock_pin_config[] __initdata = { |
| @@ -103,6 +102,9 @@ static unsigned long lubbock_pin_config[] __initdata = { · 38 unmodified lines | ||
| 103 | 102 | GPIO6_MMC_CLK, |
| 104 | 103 | GPIO8_MMC_CS0, |
| 105 | 104 | |
| 105 | + /* SA1111 chip */ | |
| 106 | + GPIO11_3_6MHz, | |
| 107 | + | |
| 106 | 108 | /* wakeup */ |
| 107 | 109 | GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, |
| 108 | 110 | }; |
| @@ -38,187 +38,11 @@ · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | #include "generic.h" |
| 40 | 40 | #include "devices.h" |
| 41 | −#include "clock.h" | |
| 42 | 41 | |
| 43 | 42 | /* |
| 44 | 43 | * Various clock factors driven by the CCCR register. |
| 45 | 44 | */ |
| 46 | 45 | |
| 47 | −/* Crystal Frequency to Memory Frequency Multiplier (L) */ | |
| 48 | −static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, }; | |
| 49 | − | |
| 50 | −/* Memory Frequency to Run Mode Frequency Multiplier (M) */ | |
| 51 | −static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 }; | |
| 52 | − | |
| 53 | −/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */ | |
| 54 | −/* Note: we store the value N * 2 here. */ | |
| 55 | −static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 }; | |
| 56 | − | |
| 57 | −/* Crystal clock */ | |
| 58 | −#define BASE_CLK 3686400 | |
| 59 | − | |
| 60 | −/* | |
| 61 | − * Get the clock frequency as reflected by CCCR and the turbo flag. | |
| 62 | − * We assume these values have been applied via a fcs. | |
| 63 | − * If info is not 0 we also display the current settings. | |
| 64 | − */ | |
| 65 | −unsigned int pxa25x_get_clk_frequency_khz(int info) | |
| 66 | −{ | |
| 67 | − unsigned long cccr, turbo; | |
| 68 | − unsigned int l, L, m, M, n2, N; | |
| 69 | − | |
| 70 | − cccr = CCCR; | |
| 71 | − asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) ); | |
| 72 | − | |
| 73 | − l = L_clk_mult[(cccr >> 0) & 0x1f]; | |
| 74 | − m = M_clk_mult[(cccr >> 5) & 0x03]; | |
| 75 | − n2 = N2_clk_mult[(cccr >> 7) & 0x07]; | |
| 76 | − | |
| 77 | − L = l * BASE_CLK; | |
| 78 | − M = m * L; | |
| 79 | − N = n2 * M / 2; | |
| 80 | − | |
| 81 | − if(info) | |
| 82 | − { | |
| 83 | − L += 5000; | |
| 84 | − printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n", | |
| 85 | − L / 1000000, (L % 1000000) / 10000, l ); | |
| 86 | − M += 5000; | |
| 87 | − printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n", | |
| 88 | − M / 1000000, (M % 1000000) / 10000, m ); | |
| 89 | − N += 5000; | |
| 90 | − printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n", | |
| 91 | − N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5, | |
| 92 | − (turbo & 1) ? "" : "in" ); | |
| 93 | − } | |
| 94 | − | |
| 95 | − return (turbo & 1) ? (N/1000) : (M/1000); | |
| 96 | −} | |
| 97 | − | |
| 98 | −static unsigned long clk_pxa25x_mem_getrate(struct clk *clk) | |
| 99 | −{ | |
| 100 | − return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK; | |
| 101 | −} | |
| 102 | − | |
| 103 | −static const struct clkops clk_pxa25x_mem_ops = { | |
| 104 | − .enable = clk_dummy_enable, | |
| 105 | − .disable = clk_dummy_disable, | |
| 106 | − .getrate = clk_pxa25x_mem_getrate, | |
| 107 | −}; | |
| 108 | − | |
| 109 | −static const struct clkops clk_pxa25x_lcd_ops = { | |
| 110 | − .enable = clk_pxa2xx_cken_enable, | |
| 111 | − .disable = clk_pxa2xx_cken_disable, | |
| 112 | − .getrate = clk_pxa25x_mem_getrate, | |
| 113 | −}; | |
| 114 | − | |
| 115 | −static unsigned long gpio12_config_32k[] = { | |
| 116 | − GPIO12_32KHz, | |
| 117 | −}; | |
| 118 | − | |
| 119 | −static unsigned long gpio12_config_gpio[] = { | |
| 120 | − GPIO12_GPIO, | |
| 121 | −}; | |
| 122 | − | |
| 123 | −static void clk_gpio12_enable(struct clk *clk) | |
| 124 | −{ | |
| 125 | − pxa2xx_mfp_config(gpio12_config_32k, 1); | |
| 126 | −} | |
| 127 | − | |
| 128 | −static void clk_gpio12_disable(struct clk *clk) | |
| 129 | −{ | |
| 130 | − pxa2xx_mfp_config(gpio12_config_gpio, 1); | |
| 131 | −} | |
| 132 | − | |
| 133 | −static const struct clkops clk_pxa25x_gpio12_ops = { | |
| 134 | − .enable = clk_gpio12_enable, | |
| 135 | − .disable = clk_gpio12_disable, | |
| 136 | −}; | |
| 137 | − | |
| 138 | −static unsigned long gpio11_config_3m6[] = { | |
| 139 | − GPIO11_3_6MHz, | |
| 140 | −}; | |
| 141 | − | |
| 142 | −static unsigned long gpio11_config_gpio[] = { | |
| 143 | − GPIO11_GPIO, | |
| 144 | −}; | |
| 145 | − | |
| 146 | −static void clk_gpio11_enable(struct clk *clk) | |
| 147 | −{ | |
| 148 | − pxa2xx_mfp_config(gpio11_config_3m6, 1); | |
| 149 | −} | |
| 150 | − | |
| 151 | −static void clk_gpio11_disable(struct clk *clk) | |
| 152 | −{ | |
| 153 | − pxa2xx_mfp_config(gpio11_config_gpio, 1); | |
| 154 | −} | |
| 155 | − | |
| 156 | −static const struct clkops clk_pxa25x_gpio11_ops = { | |
| 157 | − .enable = clk_gpio11_enable, | |
| 158 | − .disable = clk_gpio11_disable, | |
| 159 | −}; | |
| 160 | − | |
| 161 | −/* | |
| 162 | − * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz) | |
| 163 | − * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz | |
| 164 | − * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) | |
| 165 | − */ | |
| 166 | − | |
| 167 | −/* | |
| 168 | − * PXA 2xx clock declarations. | |
| 169 | − */ | |
| 170 | −static DEFINE_PXA2_CKEN(pxa25x_hwuart, HWUART, 14745600, 1); | |
| 171 | −static DEFINE_PXA2_CKEN(pxa25x_ffuart, FFUART, 14745600, 1); | |
| 172 | −static DEFINE_PXA2_CKEN(pxa25x_btuart, BTUART, 14745600, 1); | |
| 173 | −static DEFINE_PXA2_CKEN(pxa25x_stuart, STUART, 14745600, 1); | |
| 174 | −static DEFINE_PXA2_CKEN(pxa25x_usb, USB, 47923000, 5); | |
| 175 | −static DEFINE_PXA2_CKEN(pxa25x_mmc, MMC, 19169000, 0); | |
| 176 | −static DEFINE_PXA2_CKEN(pxa25x_i2c, I2C, 31949000, 0); | |
| 177 | −static DEFINE_PXA2_CKEN(pxa25x_ssp, SSP, 3686400, 0); | |
| 178 | −static DEFINE_PXA2_CKEN(pxa25x_nssp, NSSP, 3686400, 0); | |
| 179 | −static DEFINE_PXA2_CKEN(pxa25x_assp, ASSP, 3686400, 0); | |
| 180 | −static DEFINE_PXA2_CKEN(pxa25x_pwm0, PWM0, 3686400, 0); | |
| 181 | −static DEFINE_PXA2_CKEN(pxa25x_pwm1, PWM1, 3686400, 0); | |
| 182 | −static DEFINE_PXA2_CKEN(pxa25x_ac97, AC97, 24576000, 0); | |
| 183 | −static DEFINE_PXA2_CKEN(pxa25x_i2s, I2S, 14745600, 0); | |
| 184 | −static DEFINE_PXA2_CKEN(pxa25x_ficp, FICP, 47923000, 0); | |
| 185 | − | |
| 186 | −static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops); | |
| 187 | −static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0); | |
| 188 | −static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0); | |
| 189 | −static DEFINE_CLK(pxa25x_mem, &clk_pxa25x_mem_ops, 0, 0); | |
| 190 | − | |
| 191 | −static struct clk_lookup pxa25x_clkregs[] = { | |
| 192 | − INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL), | |
| 193 | − INIT_CLKREG(&clk_pxa25x_ffuart, "pxa2xx-uart.0", NULL), | |
| 194 | − INIT_CLKREG(&clk_pxa25x_btuart, "pxa2xx-uart.1", NULL), | |
| 195 | − INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-uart.2", NULL), | |
| 196 | − INIT_CLKREG(&clk_pxa25x_usb, "pxa25x-udc", NULL), | |
| 197 | − INIT_CLKREG(&clk_pxa25x_mmc, "pxa2xx-mci.0", NULL), | |
| 198 | − INIT_CLKREG(&clk_pxa25x_i2c, "pxa2xx-i2c.0", NULL), | |
| 199 | − INIT_CLKREG(&clk_pxa25x_ssp, "pxa25x-ssp.0", NULL), | |
| 200 | − INIT_CLKREG(&clk_pxa25x_nssp, "pxa25x-nssp.1", NULL), | |
| 201 | − INIT_CLKREG(&clk_pxa25x_assp, "pxa25x-nssp.2", NULL), | |
| 202 | − INIT_CLKREG(&clk_pxa25x_pwm0, "pxa25x-pwm.0", NULL), | |
| 203 | − INIT_CLKREG(&clk_pxa25x_pwm1, "pxa25x-pwm.1", NULL), | |
| 204 | − INIT_CLKREG(&clk_pxa25x_i2s, "pxa2xx-i2s", NULL), | |
| 205 | − INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-ir", "UARTCLK"), | |
| 206 | − INIT_CLKREG(&clk_pxa25x_ficp, "pxa2xx-ir", "FICPCLK"), | |
| 207 | − INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"), | |
| 208 | − INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), | |
| 209 | − INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), | |
| 210 | − INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), | |
| 211 | −#ifdef CONFIG_CPU_PXA26x | |
| 212 | − INIT_CLKREG(&clk_dummy, "pxa26x-gpio", NULL), | |
| 213 | −#else | |
| 214 | − INIT_CLKREG(&clk_dummy, "pxa25x-gpio", NULL), | |
| 215 | −#endif | |
| 216 | − INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), | |
| 217 | −}; | |
| 218 | − | |
| 219 | −static struct clk_lookup pxa25x_hwuart_clkreg = | |
| 220 | − INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL); | |
| 221 | − | |
| 222 | 46 | #ifdef CONFIG_PM |
| 223 | 47 | |
| 224 | 48 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
| @@ -374,8 +198,6 @@ static int __init pxa25x_init(void) · 149 unmodified lines | ||
| 374 | 198 | |
| 375 | 199 | reset_status = RCSR; |
| 376 | 200 | |
| 377 | − clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs)); | |
| 378 | − | |
| 379 | 201 | if ((ret = pxa_init_dma(IRQ_DMA, 16))) |
| 380 | 202 | return ret; |
| 381 | 203 | |
| @@ -383,7 +205,6 @@ static int __init pxa25x_init(void) · 1 unmodified line | ||
| 383 | 205 | |
| 384 | 206 | register_syscore_ops(&pxa_irq_syscore_ops); |
| 385 | 207 | register_syscore_ops(&pxa2xx_mfp_syscore_ops); |
| 386 | − register_syscore_ops(&pxa2xx_clock_syscore_ops); | |
| 387 | 208 | |
| 388 | 209 | pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info); |
| 389 | 210 | ret = platform_add_devices(pxa25x_devices, |
| @@ -392,10 +213,6 @@ static int __init pxa25x_init(void) · 2 unmodified lines | ||
| 392 | 213 | return ret; |
| 393 | 214 | } |
| 394 | 215 | |
| 395 | − /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */ | |
| 396 | − if (cpu_is_pxa255()) | |
| 397 | − clkdev_add(&pxa25x_hwuart_clkreg); | |
| 398 | − | |
| 399 | 216 | return ret; |
| 400 | 217 | } |
| 401 | 218 | |
| @@ -37,7 +37,8 @@ · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | #include "generic.h" |
| 39 | 39 | #include "devices.h" |
| 40 | −#include "clock.h" | |
| 40 | +#include <linux/clk-provider.h> | |
| 41 | +#include <linux/clkdev.h> | |
| 41 | 42 | |
| 42 | 43 | void pxa27x_clear_otgph(void) |
| 43 | 44 | { |
| @@ -73,174 +74,6 @@ void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio) · 29 unmodified lines | ||
| 73 | 74 | } |
| 74 | 75 | EXPORT_SYMBOL_GPL(pxa27x_configure_ac97reset); |
| 75 | 76 | |
| 76 | −/* Crystal clock: 13MHz */ | |
| 77 | −#define BASE_CLK 13000000 | |
| 78 | − | |
| 79 | −/* | |
| 80 | − * Get the clock frequency as reflected by CCSR and the turbo flag. | |
| 81 | − * We assume these values have been applied via a fcs. | |
| 82 | − * If info is not 0 we also display the current settings. | |
| 83 | − */ | |
| 84 | −unsigned int pxa27x_get_clk_frequency_khz(int info) | |
| 85 | −{ | |
| 86 | − unsigned long ccsr, clkcfg; | |
| 87 | − unsigned int l, L, m, M, n2, N, S; | |
| 88 | − int cccr_a, t, ht, b; | |
| 89 | − | |
| 90 | − ccsr = CCSR; | |
| 91 | − cccr_a = CCCR & (1 << 25); | |
| 92 | − | |
| 93 | − /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ | |
| 94 | − asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); | |
| 95 | − t = clkcfg & (1 << 0); | |
| 96 | − ht = clkcfg & (1 << 2); | |
| 97 | − b = clkcfg & (1 << 3); | |
| 98 | − | |
| 99 | − l = ccsr & 0x1f; | |
| 100 | − n2 = (ccsr>>7) & 0xf; | |
| 101 | − m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; | |
| 102 | − | |
| 103 | − L = l * BASE_CLK; | |
| 104 | − N = (L * n2) / 2; | |
| 105 | − M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); | |
| 106 | − S = (b) ? L : (L/2); | |
| 107 | − | |
| 108 | − if (info) { | |
| 109 | − printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n", | |
| 110 | − L / 1000000, (L % 1000000) / 10000, l ); | |
| 111 | − printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n", | |
| 112 | − N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5, | |
| 113 | − (t) ? "" : "in" ); | |
| 114 | − printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n", | |
| 115 | − M / 1000000, (M % 1000000) / 10000, m ); | |
| 116 | − printk( KERN_INFO "System bus clock: %d.%02dMHz \n", | |
| 117 | − S / 1000000, (S % 1000000) / 10000 ); | |
| 118 | − } | |
| 119 | − | |
| 120 | − return (t) ? (N/1000) : (L/1000); | |
| 121 | −} | |
| 122 | − | |
| 123 | −/* | |
| 124 | − * Return the current mem clock frequency as reflected by CCCR[A], B, and L | |
| 125 | − */ | |
| 126 | −static unsigned long clk_pxa27x_mem_getrate(struct clk *clk) | |
| 127 | −{ | |
| 128 | − unsigned long ccsr, clkcfg; | |
| 129 | − unsigned int l, L, m, M; | |
| 130 | − int cccr_a, b; | |
| 131 | − | |
| 132 | − ccsr = CCSR; | |
| 133 | − cccr_a = CCCR & (1 << 25); | |
| 134 | − | |
| 135 | − /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ | |
| 136 | − asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); | |
| 137 | − b = clkcfg & (1 << 3); | |
| 138 | − | |
| 139 | − l = ccsr & 0x1f; | |
| 140 | − m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; | |
| 141 | − | |
| 142 | − L = l * BASE_CLK; | |
| 143 | − M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); | |
| 144 | − | |
| 145 | − return M; | |
| 146 | −} | |
| 147 | − | |
| 148 | −static const struct clkops clk_pxa27x_mem_ops = { | |
| 149 | − .enable = clk_dummy_enable, | |
| 150 | − .disable = clk_dummy_disable, | |
| 151 | − .getrate = clk_pxa27x_mem_getrate, | |
| 152 | −}; | |
| 153 | − | |
| 154 | −/* | |
| 155 | − * Return the current LCD clock frequency in units of 10kHz as | |
| 156 | − */ | |
| 157 | −static unsigned int pxa27x_get_lcdclk_frequency_10khz(void) | |
| 158 | −{ | |
| 159 | − unsigned long ccsr; | |
| 160 | − unsigned int l, L, k, K; | |
| 161 | − | |
| 162 | − ccsr = CCSR; | |
| 163 | − | |
| 164 | − l = ccsr & 0x1f; | |
| 165 | − k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4; | |
| 166 | − | |
| 167 | − L = l * BASE_CLK; | |
| 168 | − K = L / k; | |
| 169 | − | |
| 170 | − return (K / 10000); | |
| 171 | −} | |
| 172 | − | |
| 173 | −static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) | |
| 174 | −{ | |
| 175 | − return pxa27x_get_lcdclk_frequency_10khz() * 10000; | |
| 176 | −} | |
| 177 | − | |
| 178 | −static const struct clkops clk_pxa27x_lcd_ops = { | |
| 179 | − .enable = clk_pxa2xx_cken_enable, | |
| 180 | − .disable = clk_pxa2xx_cken_disable, | |
| 181 | − .getrate = clk_pxa27x_lcd_getrate, | |
| 182 | −}; | |
| 183 | − | |
| 184 | −static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1); | |
| 185 | −static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1); | |
| 186 | −static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1); | |
| 187 | −static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0); | |
| 188 | −static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0); | |
| 189 | −static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5); | |
| 190 | −static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0); | |
| 191 | −static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0); | |
| 192 | −static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0); | |
| 193 | −static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0); | |
| 194 | −static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0); | |
| 195 | −static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0); | |
| 196 | −static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0); | |
| 197 | −static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0); | |
| 198 | −static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0); | |
| 199 | −static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0); | |
| 200 | −static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0); | |
| 201 | −static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0); | |
| 202 | −static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0); | |
| 203 | −static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0); | |
| 204 | −static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0); | |
| 205 | −static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0); | |
| 206 | −static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0); | |
| 207 | − | |
| 208 | −static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops); | |
| 209 | −static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops); | |
| 210 | −static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0); | |
| 211 | − | |
| 212 | −static struct clk_lookup pxa27x_clkregs[] = { | |
| 213 | − INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL), | |
| 214 | − INIT_CLKREG(&clk_pxa27x_camera, "pxa27x-camera.0", NULL), | |
| 215 | − INIT_CLKREG(&clk_pxa27x_ffuart, "pxa2xx-uart.0", NULL), | |
| 216 | − INIT_CLKREG(&clk_pxa27x_btuart, "pxa2xx-uart.1", NULL), | |
| 217 | − INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-uart.2", NULL), | |
| 218 | − INIT_CLKREG(&clk_pxa27x_i2s, "pxa2xx-i2s", NULL), | |
| 219 | − INIT_CLKREG(&clk_pxa27x_i2c, "pxa2xx-i2c.0", NULL), | |
| 220 | − INIT_CLKREG(&clk_pxa27x_usb, "pxa27x-udc", NULL), | |
| 221 | − INIT_CLKREG(&clk_pxa27x_mmc, "pxa2xx-mci.0", NULL), | |
| 222 | − INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-ir", "UARTCLK"), | |
| 223 | − INIT_CLKREG(&clk_pxa27x_ficp, "pxa2xx-ir", "FICPCLK"), | |
| 224 | − INIT_CLKREG(&clk_pxa27x_usbhost, "pxa27x-ohci", NULL), | |
| 225 | − INIT_CLKREG(&clk_pxa27x_pwri2c, "pxa2xx-i2c.1", NULL), | |
| 226 | − INIT_CLKREG(&clk_pxa27x_keypad, "pxa27x-keypad", NULL), | |
| 227 | − INIT_CLKREG(&clk_pxa27x_ssp1, "pxa27x-ssp.0", NULL), | |
| 228 | − INIT_CLKREG(&clk_pxa27x_ssp2, "pxa27x-ssp.1", NULL), | |
| 229 | − INIT_CLKREG(&clk_pxa27x_ssp3, "pxa27x-ssp.2", NULL), | |
| 230 | − INIT_CLKREG(&clk_pxa27x_pwm0, "pxa27x-pwm.0", NULL), | |
| 231 | − INIT_CLKREG(&clk_pxa27x_pwm1, "pxa27x-pwm.1", NULL), | |
| 232 | − INIT_CLKREG(&clk_pxa27x_ac97, NULL, "AC97CLK"), | |
| 233 | − INIT_CLKREG(&clk_pxa27x_ac97conf, NULL, "AC97CONFCLK"), | |
| 234 | − INIT_CLKREG(&clk_pxa27x_msl, NULL, "MSLCLK"), | |
| 235 | − INIT_CLKREG(&clk_pxa27x_usim, NULL, "USIMCLK"), | |
| 236 | − INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"), | |
| 237 | − INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), | |
| 238 | − INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), | |
| 239 | − INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), | |
| 240 | − INIT_CLKREG(&clk_dummy, "pxa27x-gpio", NULL), | |
| 241 | − INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), | |
| 242 | −}; | |
| 243 | − | |
| 244 | 77 | #ifdef CONFIG_PM |
| 245 | 78 | |
| 246 | 79 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
| @@ -466,8 +299,6 @@ static int __init pxa27x_init(void) · 219 unmodified lines | ||
| 466 | 299 | |
| 467 | 300 | reset_status = RCSR; |
| 468 | 301 | |
| 469 | − clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs)); | |
| 470 | − | |
| 471 | 302 | if ((ret = pxa_init_dma(IRQ_DMA, 32))) |
| 472 | 303 | return ret; |
| 473 | 304 | |
| @@ -475,10 +306,13 @@ static int __init pxa27x_init(void) · 1 unmodified line | ||
| 475 | 306 | |
| 476 | 307 | register_syscore_ops(&pxa_irq_syscore_ops); |
| 477 | 308 | register_syscore_ops(&pxa2xx_mfp_syscore_ops); |
| 478 | − register_syscore_ops(&pxa2xx_clock_syscore_ops); | |
| 479 | 309 | |
| 480 | − pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info); | |
| 481 | − ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | |
| 310 | + if (!of_have_populated_dt()) { | |
| 311 | + pxa_register_device(&pxa27x_device_gpio, | |
| 312 | + &pxa27x_gpio_info); | |
| 313 | + ret = platform_add_devices(devices, | |
| 314 | + ARRAY_SIZE(devices)); | |
| 315 | + } | |
| 482 | 316 | } |
| 483 | 317 | |
| 484 | 318 | return ret; |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #include "generic.h" |
| 24 | 24 | #include "devices.h" |
| 25 | −#include "clock.h" | |
| 26 | 25 | |
| 27 | 26 | static struct mfp_addr_map pxa300_mfp_addr_map[] __initdata = { |
| 28 | 27 | |
| @@ -84,32 +83,15 @@ static struct mfp_addr_map pxa310_mfp_addr_map[] __initdata = { · 55 unmodified lines | ||
| 84 | 83 | MFP_ADDR_END, |
| 85 | 84 | }; |
| 86 | 85 | |
| 87 | −static DEFINE_PXA3_CKEN(common_nand, NAND, 156000000, 0); | |
| 88 | −static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0); | |
| 89 | − | |
| 90 | −static struct clk_lookup common_clkregs[] = { | |
| 91 | − INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL), | |
| 92 | − INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), | |
| 93 | −}; | |
| 94 | − | |
| 95 | −static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0); | |
| 96 | − | |
| 97 | −static struct clk_lookup pxa310_clkregs[] = { | |
| 98 | − INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", NULL), | |
| 99 | −}; | |
| 100 | − | |
| 101 | 86 | static int __init pxa300_init(void) |
| 102 | 87 | { |
| 103 | 88 | if (cpu_is_pxa300() || cpu_is_pxa310()) { |
| 104 | 89 | mfp_init_base(io_p2v(MFPR_BASE)); |
| 105 | 90 | mfp_init_addr(pxa300_mfp_addr_map); |
| 106 | − clkdev_add_table(ARRAY_AND_SIZE(common_clkregs)); | |
| 107 | 91 | } |
| 108 | 92 | |
| 109 | − if (cpu_is_pxa310()) { | |
| 93 | + if (cpu_is_pxa310()) | |
| 110 | 94 | mfp_init_addr(pxa310_mfp_addr_map); |
| 111 | − clkdev_add_table(ARRAY_AND_SIZE(pxa310_clkregs)); | |
| 112 | − } | |
| 113 | 95 | |
| 114 | 96 | return 0; |
| 115 | 97 | } |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #include "generic.h" |
| 24 | 24 | #include "devices.h" |
| 25 | −#include "clock.h" | |
| 26 | 25 | |
| 27 | 26 | static struct mfp_addr_map pxa320_mfp_addr_map[] __initdata = { |
| 28 | 27 | |
| @@ -78,20 +77,11 @@ static struct mfp_addr_map pxa320_mfp_addr_map[] __initdata = { · 49 unmodified lines | ||
| 78 | 77 | MFP_ADDR_END, |
| 79 | 78 | }; |
| 80 | 79 | |
| 81 | −static DEFINE_PXA3_CKEN(pxa320_nand, NAND, 104000000, 0); | |
| 82 | −static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0); | |
| 83 | − | |
| 84 | −static struct clk_lookup pxa320_clkregs[] = { | |
| 85 | − INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL), | |
| 86 | − INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), | |
| 87 | −}; | |
| 88 | − | |
| 89 | 80 | static int __init pxa320_init(void) |
| 90 | 81 | { |
| 91 | 82 | if (cpu_is_pxa320()) { |
| 92 | 83 | mfp_init_base(io_p2v(MFPR_BASE)); |
| 93 | 84 | mfp_init_addr(pxa320_mfp_addr_map); |
| 94 | − clkdev_add_table(ARRAY_AND_SIZE(pxa320_clkregs)); | |
| 95 | 85 | } |
| 96 | 86 | |
| 97 | 87 | return 0; |
| @@ -37,67 +37,11 @@ · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | #include "generic.h" |
| 39 | 39 | #include "devices.h" |
| 40 | −#include "clock.h" | |
| 41 | 40 | |
| 42 | 41 | #define PECR_IE(n) ((1 << ((n) * 2)) << 28) |
| 43 | 42 | #define PECR_IS(n) ((1 << ((n) * 2)) << 29) |
| 44 | 43 | |
| 45 | 44 | extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int)); |
| 46 | − | |
| 47 | −static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1); | |
| 48 | −static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1); | |
| 49 | −static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1); | |
| 50 | −static DEFINE_PXA3_CKEN(pxa3xx_i2c, I2C, 32842000, 0); | |
| 51 | −static DEFINE_PXA3_CKEN(pxa3xx_udc, UDC, 48000000, 5); | |
| 52 | −static DEFINE_PXA3_CKEN(pxa3xx_usbh, USBH, 48000000, 0); | |
| 53 | −static DEFINE_PXA3_CKEN(pxa3xx_u2d, USB2, 48000000, 0); | |
| 54 | −static DEFINE_PXA3_CKEN(pxa3xx_keypad, KEYPAD, 32768, 0); | |
| 55 | −static DEFINE_PXA3_CKEN(pxa3xx_ssp1, SSP1, 13000000, 0); | |
| 56 | −static DEFINE_PXA3_CKEN(pxa3xx_ssp2, SSP2, 13000000, 0); | |
| 57 | −static DEFINE_PXA3_CKEN(pxa3xx_ssp3, SSP3, 13000000, 0); | |
| 58 | −static DEFINE_PXA3_CKEN(pxa3xx_ssp4, SSP4, 13000000, 0); | |
| 59 | −static DEFINE_PXA3_CKEN(pxa3xx_pwm0, PWM0, 13000000, 0); | |
| 60 | −static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0); | |
| 61 | −static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); | |
| 62 | −static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); | |
| 63 | −static DEFINE_PXA3_CKEN(pxa3xx_gpio, GPIO, 13000000, 0); | |
| 64 | − | |
| 65 | −static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); | |
| 66 | −static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops); | |
| 67 | −static DEFINE_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops); | |
| 68 | −static DEFINE_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops); | |
| 69 | −static DEFINE_CLK(pxa3xx_pout, &clk_pxa3xx_pout_ops, 13000000, 70); | |
| 70 | − | |
| 71 | −static struct clk_lookup pxa3xx_clkregs[] = { | |
| 72 | − INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), | |
| 73 | − /* Power I2C clock is always on */ | |
| 74 | − INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), | |
| 75 | − INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL), | |
| 76 | − INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"), | |
| 77 | − INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"), | |
| 78 | − INIT_CLKREG(&clk_pxa3xx_ffuart, "pxa2xx-uart.0", NULL), | |
| 79 | − INIT_CLKREG(&clk_pxa3xx_btuart, "pxa2xx-uart.1", NULL), | |
| 80 | − INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-uart.2", NULL), | |
| 81 | − INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-ir", "UARTCLK"), | |
| 82 | − INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL), | |
| 83 | − INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL), | |
| 84 | − INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL), | |
| 85 | − INIT_CLKREG(&clk_pxa3xx_u2d, "pxa3xx-u2d", NULL), | |
| 86 | − INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL), | |
| 87 | − INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa3xx-ssp.0", NULL), | |
| 88 | − INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa3xx-ssp.1", NULL), | |
| 89 | − INIT_CLKREG(&clk_pxa3xx_ssp3, "pxa3xx-ssp.2", NULL), | |
| 90 | − INIT_CLKREG(&clk_pxa3xx_ssp4, "pxa3xx-ssp.3", NULL), | |
| 91 | − INIT_CLKREG(&clk_pxa3xx_pwm0, "pxa27x-pwm.0", NULL), | |
| 92 | − INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL), | |
| 93 | − INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), | |
| 94 | − INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), | |
| 95 | − INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL), | |
| 96 | − INIT_CLKREG(&clk_pxa3xx_gpio, "pxa3xx-gpio", NULL), | |
| 97 | − INIT_CLKREG(&clk_pxa3xx_gpio, "pxa93x-gpio", NULL), | |
| 98 | − INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), | |
| 99 | −}; | |
| 100 | − | |
| 101 | 45 | #ifdef CONFIG_PM |
| 102 | 46 | |
| 103 | 47 | #define ISRAM_START 0x5c000000 |
| @@ -476,8 +420,6 @@ static int __init pxa3xx_init(void) · 372 unmodified lines | ||
| 476 | 420 | */ |
| 477 | 421 | ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S); |
| 478 | 422 | |
| 479 | − clkdev_add_table(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs)); | |
| 480 | − | |
| 481 | 423 | if ((ret = pxa_init_dma(IRQ_DMA, 32))) |
| 482 | 424 | return ret; |
| 483 | 425 | |
| @@ -485,7 +427,6 @@ static int __init pxa3xx_init(void) · 1 unmodified line | ||
| 485 | 427 | |
| 486 | 428 | register_syscore_ops(&pxa_irq_syscore_ops); |
| 487 | 429 | register_syscore_ops(&pxa3xx_mfp_syscore_ops); |
| 488 | − register_syscore_ops(&pxa3xx_clock_syscore_ops); | |
| 489 | 430 | |
| 490 | 431 | if (of_have_populated_dt()) |
| 491 | 432 | return 0; |
| @@ -56,7 +56,6 @@ · 55 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | #include "generic.h" |
| 58 | 58 | #include "devices.h" |
| 59 | −#include "clock.h" | |
| 60 | 59 | |
| 61 | 60 | /* common GPIO definitions */ |
| 62 | 61 | |
| @@ -59,7 +59,6 @@ · 58 unmodified lines | ||
| 59 | 59 | #include <asm/mach/sharpsl_param.h> |
| 60 | 60 | |
| 61 | 61 | #include "generic.h" |
| 62 | −#include "clock.h" | |
| 63 | 62 | #include "devices.h" |
| 64 | 63 | |
| 65 | 64 | static unsigned long tosa_pin_config[] = { |
| @@ -139,7 +139,7 @@ config MACH_ARMADILLO800EVA · 138 unmodified lines | ||
| 139 | 139 | select ARCH_REQUIRE_GPIOLIB |
| 140 | 140 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
| 141 | 141 | select SMSC_PHY if SH_ETH |
| 142 | − select SND_SOC_WM8978 if SND_SIMPLE_CARD | |
| 142 | + select SND_SOC_WM8978 if SND_SIMPLE_CARD && I2C | |
| 143 | 143 | select USE_OF |
| 144 | 144 | |
| 145 | 145 | config MACH_BOCKW |
| @@ -148,7 +148,7 @@ config MACH_BOCKW · 2 unmodified lines | ||
| 148 | 148 | select ARCH_REQUIRE_GPIOLIB |
| 149 | 149 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
| 150 | 150 | select SND_SOC_AK4554 if SND_SIMPLE_CARD |
| 151 | − select SND_SOC_AK4642 if SND_SIMPLE_CARD | |
| 151 | + select SND_SOC_AK4642 if SND_SIMPLE_CARD && I2C | |
| 152 | 152 | select USE_OF |
| 153 | 153 | |
| 154 | 154 | config MACH_BOCKW_REFERENCE |
| @@ -1,5 +1,6 @@ | ||
| 1 | −config ARCH_SOCFPGA | |
| 1 | +menuconfig ARCH_SOCFPGA | |
| 2 | 2 | bool "Altera SOCFPGA family" if ARCH_MULTI_V7 |
| 3 | + select ARCH_SUPPORTS_BIG_ENDIAN | |
| 3 | 4 | select ARM_AMBA |
| 4 | 5 | select ARM_GIC |
| 5 | 6 | select CACHE_L2X0 |
| @@ -8,3 +9,11 @@ config ARCH_SOCFPGA · 2 unmodified lines | ||
| 8 | 9 | select HAVE_ARM_SCU |
| 9 | 10 | select HAVE_ARM_TWD if SMP |
| 10 | 11 | select MFD_SYSCON |
| 12 | + | |
| 13 | +if ARCH_SOCFPGA | |
| 14 | +config SOCFPGA_SUSPEND | |
| 15 | + bool "Suspend to RAM on SOCFPGA" | |
| 16 | + help | |
| 17 | + Select this if you want to enable Suspend-to-RAM on SOCFPGA | |
| 18 | + platforms. | |
| 19 | +endif | |
| @@ -4,3 +4,4 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | obj-y := socfpga.o |
| 6 | 6 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o |
| 7 | +obj-$(CONFIG_SOCFPGA_SUSPEND) += pm.o self-refresh.o | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Copyright 2012 Pavel Machek <pavel@denx.de> |
| 3 | − * Copyright (C) 2012 Altera Corporation | |
| 3 | + * Copyright (C) 2012-2015 Altera Corporation | |
| 4 | 4 | * |
| 5 | 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | 6 | * it under the terms of the GNU General Public License as published by |
| @@ -25,21 +25,24 @@ · 18 unmodified lines | ||
| 25 | 25 | #define SOCFPGA_RSTMGR_MODPERRST 0x14 |
| 26 | 26 | #define SOCFPGA_RSTMGR_BRGMODRST 0x1c |
| 27 | 27 | |
| 28 | +#define SOCFPGA_A10_RSTMGR_MODMPURST 0x20 | |
| 29 | + | |
| 28 | 30 | /* System Manager bits */ |
| 29 | 31 | #define RSTMGR_CTRL_SWCOLDRSTREQ 0x1 /* Cold Reset */ |
| 30 | 32 | #define RSTMGR_CTRL_SWWARMRSTREQ 0x2 /* Warm Reset */ |
| 31 | 33 | |
| 32 | 34 | #define RSTMGR_MPUMODRST_CPU1 0x2 /* CPU1 Reset */ |
| 33 | 35 | |
| 34 | −extern void __iomem *socfpga_scu_base_addr; | |
| 35 | − | |
| 36 | 36 | extern void socfpga_init_clocks(void); |
| 37 | 37 | extern void socfpga_sysmgr_init(void); |
| 38 | 38 | |
| 39 | 39 | extern void __iomem *sys_manager_base_addr; |
| 40 | 40 | extern void __iomem *rst_manager_base_addr; |
| 41 | +extern void __iomem *sdr_ctl_base_addr; | |
| 42 | + | |
| 43 | +u32 socfpga_sdram_self_refresh(u32 sdr_base); | |
| 44 | +extern unsigned int socfpga_sdram_self_refresh_sz; | |
| 41 | 45 | |
| 42 | −extern struct smp_operations socfpga_smp_ops; | |
| 43 | 46 | extern char secondary_trampoline, secondary_trampoline_end; |
| 44 | 47 | |
| 45 | 48 | extern unsigned long socfpga_cpu1start_addr; |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/linkage.h> |
| 11 | 11 | #include <linux/init.h> |
| 12 | 12 | #include <asm/memory.h> |
| 13 | +#include <asm/assembler.h> | |
| 13 | 14 | |
| 14 | 15 | .arch armv7-a |
| 15 | 16 | |
| @@ -18,12 +19,14 @@ ENTRY(secondary_trampoline) · 2 unmodified lines | ||
| 18 | 19 | * Thus, we can just subtract the PAGE_OFFSET to get the physical |
| 19 | 20 | * address of &cpu1start_addr. This would not work for platforms |
| 20 | 21 | * where the physical memory does not start at 0x0. |
| 21 | − */ | |
| 22 | + */ | |
| 23 | +ARM_BE8(setend be) | |
| 22 | 24 | adr r0, 1f |
| 23 | 25 | ldmia r0, {r1, r2} |
| 24 | 26 | sub r2, r2, #PAGE_OFFSET |
| 25 | 27 | ldr r3, [r2] |
| 26 | 28 | ldr r4, [r3] |
| 29 | +ARM_BE8(rev r4, r4) | |
| 27 | 30 | bx r4 |
| 28 | 31 | |
| 29 | 32 | .align |
| @@ -54,32 +54,43 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) · 53 unmodified lines | ||
| 54 | 54 | return 0; |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | −/* | |
| 58 | − * Initialise the CPU possible map early - this describes the CPUs | |
| 59 | − * which may be present or become present in the system. | |
| 60 | − */ | |
| 61 | −static void __init socfpga_smp_init_cpus(void) | |
| 57 | +static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle) | |
| 62 | 58 | { |
| 63 | − unsigned int i, ncores; | |
| 59 | + int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; | |
| 64 | 60 | |
| 65 | − ncores = scu_get_core_count(socfpga_scu_base_addr); | |
| 61 | + if (socfpga_cpu1start_addr) { | |
| 62 | + writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr + | |
| 63 | + SOCFPGA_A10_RSTMGR_MODMPURST); | |
| 64 | + memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); | |
| 66 | 65 | |
| 67 | − for (i = 0; i < ncores; i++) | |
| 68 | − set_cpu_possible(i, true); | |
| 66 | + writel(virt_to_phys(secondary_startup), | |
| 67 | + sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff)); | |
| 69 | 68 | |
| 70 | − /* sanity check */ | |
| 71 | − if (ncores > num_possible_cpus()) { | |
| 72 | − pr_warn("socfpga: no. of cores (%d) greater than configured" | |
| 73 | − "maximum of %d - clipping\n", ncores, num_possible_cpus()); | |
| 74 | − ncores = num_possible_cpus(); | |
| 69 | + flush_cache_all(); | |
| 70 | + smp_wmb(); | |
| 71 | + outer_clean_range(0, trampoline_size); | |
| 72 | + | |
| 73 | + /* This will release CPU #1 out of reset. */ | |
| 74 | + writel(0, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_MODMPURST); | |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | − for (i = 0; i < ncores; i++) | |
| 78 | − set_cpu_possible(i, true); | |
| 77 | + return 0; | |
| 79 | 78 | } |
| 80 | 79 | |
| 81 | 80 | static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) |
| 82 | 81 | { |
| 82 | + struct device_node *np; | |
| 83 | + void __iomem *socfpga_scu_base_addr; | |
| 84 | + | |
| 85 | + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); | |
| 86 | + if (!np) { | |
| 87 | + pr_err("%s: missing scu\n", __func__); | |
| 88 | + return; | |
| 89 | + } | |
| 90 | + | |
| 91 | + socfpga_scu_base_addr = of_iomap(np, 0); | |
| 92 | + if (!socfpga_scu_base_addr) | |
| 93 | + return; | |
| 83 | 94 | scu_enable(socfpga_scu_base_addr); |
| 84 | 95 | } |
| 85 | 96 | |
| @@ -95,11 +106,21 @@ static void socfpga_cpu_die(unsigned int cpu) · 9 unmodified lines | ||
| 95 | 106 | cpu_do_idle(); |
| 96 | 107 | } |
| 97 | 108 | |
| 98 | −struct smp_operations socfpga_smp_ops __initdata = { | |
| 99 | − .smp_init_cpus = socfpga_smp_init_cpus, | |
| 109 | +static struct smp_operations socfpga_smp_ops __initdata = { | |
| 100 | 110 | .smp_prepare_cpus = socfpga_smp_prepare_cpus, |
| 101 | 111 | .smp_boot_secondary = socfpga_boot_secondary, |
| 102 | 112 | #ifdef CONFIG_HOTPLUG_CPU |
| 103 | 113 | .cpu_die = socfpga_cpu_die, |
| 104 | 114 | #endif |
| 105 | 115 | }; |
| 116 | + | |
| 117 | +static struct smp_operations socfpga_a10_smp_ops __initdata = { | |
| 118 | + .smp_prepare_cpus = socfpga_smp_prepare_cpus, | |
| 119 | + .smp_boot_secondary = socfpga_a10_boot_secondary, | |
| 120 | +#ifdef CONFIG_HOTPLUG_CPU | |
| 121 | + .cpu_die = socfpga_cpu_die, | |
| 122 | +#endif | |
| 123 | +}; | |
| 124 | + | |
| 125 | +CPU_METHOD_OF_DECLARE(socfpga_smp, "altr,socfpga-smp", &socfpga_smp_ops); | |
| 126 | +CPU_METHOD_OF_DECLARE(socfpga_a10_smp, "altr,socfpga-a10-smp", &socfpga_a10_smp_ops); | |
| @@ -0,0 +1,149 @@ | ||
| 1 | +/* | |
| 2 | + * arch/arm/mach-socfpga/pm.c | |
| 3 | + * | |
| 4 | + * Copyright (C) 2014-2015 Altera Corporation. All rights reserved. | |
| 5 | + * | |
| 6 | + * with code from pm-imx6.c | |
| 7 | + * Copyright 2011-2014 Freescale Semiconductor, Inc. | |
| 8 | + * Copyright 2011 Linaro Ltd. | |
| 9 | + * | |
| 10 | + * This program is free software; you can redistribute it and/or modify it | |
| 11 | + * under the terms and conditions of the GNU General Public License, | |
| 12 | + * version 2, as published by the Free Software Foundation. | |
| 13 | + * | |
| 14 | + * This program is distributed in the hope it will be useful, but WITHOUT | |
| 15 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 17 | + * more details. | |
| 18 | + * | |
| 19 | + * You should have received a copy of the GNU General Public License along with | |
| 20 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | + */ | |
| 22 | + | |
| 23 | +#include <linux/bitops.h> | |
| 24 | +#include <linux/genalloc.h> | |
| 25 | +#include <linux/init.h> | |
| 26 | +#include <linux/io.h> | |
| 27 | +#include <linux/of_platform.h> | |
| 28 | +#include <linux/suspend.h> | |
| 29 | +#include <asm/suspend.h> | |
| 30 | +#include <asm/fncpy.h> | |
| 31 | +#include "core.h" | |
| 32 | + | |
| 33 | +/* Pointer to function copied to ocram */ | |
| 34 | +static u32 (*socfpga_sdram_self_refresh_in_ocram)(u32 sdr_base); | |
| 35 | + | |
| 36 | +static int socfpga_setup_ocram_self_refresh(void) | |
| 37 | +{ | |
| 38 | + struct platform_device *pdev; | |
| 39 | + phys_addr_t ocram_pbase; | |
| 40 | + struct device_node *np; | |
| 41 | + struct gen_pool *ocram_pool; | |
| 42 | + unsigned long ocram_base; | |
| 43 | + void __iomem *suspend_ocram_base; | |
| 44 | + int ret = 0; | |
| 45 | + | |
| 46 | + np = of_find_compatible_node(NULL, NULL, "mmio-sram"); | |
| 47 | + if (!np) { | |
| 48 | + pr_err("%s: Unable to find mmio-sram in dtb\n", __func__); | |
| 49 | + return -ENODEV; | |
| 50 | + } | |
| 51 | + | |
| 52 | + pdev = of_find_device_by_node(np); | |
| 53 | + if (!pdev) { | |
| 54 | + pr_warn("%s: failed to find ocram device!\n", __func__); | |
| 55 | + ret = -ENODEV; | |
| 56 | + goto put_node; | |
| 57 | + } | |
| 58 | + | |
| 59 | + ocram_pool = dev_get_gen_pool(&pdev->dev); | |
| 60 | + if (!ocram_pool) { | |
| 61 | + pr_warn("%s: ocram pool unavailable!\n", __func__); | |
| 62 | + ret = -ENODEV; | |
| 63 | + goto put_node; | |
| 64 | + } | |
| 65 | + | |
| 66 | + ocram_base = gen_pool_alloc(ocram_pool, socfpga_sdram_self_refresh_sz); | |
| 67 | + if (!ocram_base) { | |
| 68 | + pr_warn("%s: unable to alloc ocram!\n", __func__); | |
| 69 | + ret = -ENOMEM; | |
| 70 | + goto put_node; | |
| 71 | + } | |
| 72 | + | |
| 73 | + ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base); | |
| 74 | + | |
| 75 | + suspend_ocram_base = __arm_ioremap_exec(ocram_pbase, | |
| 76 | + socfpga_sdram_self_refresh_sz, | |
| 77 | + false); | |
| 78 | + if (!suspend_ocram_base) { | |
| 79 | + pr_warn("%s: __arm_ioremap_exec failed!\n", __func__); | |
| 80 | + ret = -ENOMEM; | |
| 81 | + goto put_node; | |
| 82 | + } | |
| 83 | + | |
| 84 | + /* Copy the code that puts DDR in self refresh to ocram */ | |
| 85 | + socfpga_sdram_self_refresh_in_ocram = | |
| 86 | + (void *)fncpy(suspend_ocram_base, | |
| 87 | + &socfpga_sdram_self_refresh, | |
| 88 | + socfpga_sdram_self_refresh_sz); | |
| 89 | + | |
| 90 | + WARN(!socfpga_sdram_self_refresh_in_ocram, | |
| 91 | + "could not copy function to ocram"); | |
| 92 | + if (!socfpga_sdram_self_refresh_in_ocram) | |
| 93 | + ret = -EFAULT; | |
| 94 | + | |
| 95 | +put_node: | |
| 96 | + of_node_put(np); | |
| 97 | + | |
| 98 | + return ret; | |
| 99 | +} | |
| 100 | + | |
| 101 | +static int socfpga_pm_suspend(unsigned long arg) | |
| 102 | +{ | |
| 103 | + u32 ret; | |
| 104 | + | |
| 105 | + if (!sdr_ctl_base_addr) | |
| 106 | + return -EFAULT; | |
| 107 | + | |
| 108 | + ret = socfpga_sdram_self_refresh_in_ocram((u32)sdr_ctl_base_addr); | |
| 109 | + | |
| 110 | + pr_debug("%s self-refresh loops request=%d exit=%d\n", __func__, | |
| 111 | + ret & 0xffff, (ret >> 16) & 0xffff); | |
| 112 | + | |
| 113 | + return 0; | |
| 114 | +} | |
| 115 | + | |
| 116 | +static int socfpga_pm_enter(suspend_state_t state) | |
| 117 | +{ | |
| 118 | + switch (state) { | |
| 119 | + case PM_SUSPEND_STANDBY: | |
| 120 | + case PM_SUSPEND_MEM: | |
| 121 | + outer_disable(); | |
| 122 | + cpu_suspend(0, socfpga_pm_suspend); | |
| 123 | + outer_resume(); | |
| 124 | + break; | |
| 125 | + default: | |
| 126 | + return -EINVAL; | |
| 127 | + } | |
| 128 | + return 0; | |
| 129 | +} | |
| 130 | + | |
| 131 | +static const struct platform_suspend_ops socfpga_pm_ops = { | |
| 132 | + .valid = suspend_valid_only_mem, | |
| 133 | + .enter = socfpga_pm_enter, | |
| 134 | +}; | |
| 135 | + | |
| 136 | +static int __init socfpga_pm_init(void) | |
| 137 | +{ | |
| 138 | + int ret; | |
| 139 | + | |
| 140 | + ret = socfpga_setup_ocram_self_refresh(); | |
| 141 | + if (ret) | |
| 142 | + return ret; | |
| 143 | + | |
| 144 | + suspend_set_ops(&socfpga_pm_ops); | |
| 145 | + pr_info("SoCFPGA initialized for DDR self-refresh during suspend.\n"); | |
| 146 | + | |
| 147 | + return 0; | |
| 148 | +} | |
| 149 | +arch_initcall(socfpga_pm_init); | |
| @@ -0,0 +1,136 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2014-2015 Altera 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 along with | |
| 14 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + */ | |
| 16 | +#include <linux/linkage.h> | |
| 17 | +#include <asm/assembler.h> | |
| 18 | + | |
| 19 | +#define MAX_LOOP_COUNT 1000 | |
| 20 | + | |
| 21 | +/* Register offset */ | |
| 22 | +#define SDR_CTRLGRP_LOWPWREQ_ADDR 0x54 | |
| 23 | +#define SDR_CTRLGRP_LOWPWRACK_ADDR 0x58 | |
| 24 | + | |
| 25 | +/* Bitfield positions */ | |
| 26 | +#define SELFRSHREQ_POS 3 | |
| 27 | +#define SELFRSHREQ_MASK 0x8 | |
| 28 | + | |
| 29 | +#define SELFRFSHACK_POS 1 | |
| 30 | +#define SELFRFSHACK_MASK 0x2 | |
| 31 | + | |
| 32 | + /* | |
| 33 | + * This code assumes that when the bootloader configured | |
| 34 | + * the sdram controller for the DDR on the board it | |
| 35 | + * configured the following fields depending on the DDR | |
| 36 | + * vendor/configuration: | |
| 37 | + * | |
| 38 | + * sdr.ctrlcfg.lowpwreq.selfrfshmask | |
| 39 | + * sdr.ctrlcfg.lowpwrtiming.clkdisablecycles | |
| 40 | + * sdr.ctrlcfg.dramtiming4.selfrfshexit | |
| 41 | + */ | |
| 42 | + | |
| 43 | + .arch armv7-a | |
| 44 | + .text | |
| 45 | + .align 3 | |
| 46 | + | |
| 47 | + /* | |
| 48 | + * socfpga_sdram_self_refresh | |
| 49 | + * | |
| 50 | + * r0 : sdr_ctl_base_addr | |
| 51 | + * r1 : temp storage of return value | |
| 52 | + * r2 : temp storage of register values | |
| 53 | + * r3 : loop counter | |
| 54 | + * | |
| 55 | + * return value: lower 16 bits: loop count going into self refresh | |
| 56 | + * upper 16 bits: loop count exiting self refresh | |
| 57 | + */ | |
| 58 | +ENTRY(socfpga_sdram_self_refresh) | |
| 59 | + /* Enable dynamic clock gating in the Power Control Register. */ | |
| 60 | + mrc p15, 0, r2, c15, c0, 0 | |
| 61 | + orr r2, r2, #1 | |
| 62 | + mcr p15, 0, r2, c15, c0, 0 | |
| 63 | + | |
| 64 | + /* Enable self refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 1 */ | |
| 65 | + ldr r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR] | |
| 66 | + orr r2, r2, #SELFRSHREQ_MASK | |
| 67 | + str r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR] | |
| 68 | + | |
| 69 | + /* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 1 or hit max loops */ | |
| 70 | + mov r3, #0 | |
| 71 | +while_ack_0: | |
| 72 | + ldr r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR] | |
| 73 | + and r2, r2, #SELFRFSHACK_MASK | |
| 74 | + cmp r2, #SELFRFSHACK_MASK | |
| 75 | + beq ack_1 | |
| 76 | + | |
| 77 | + add r3, #1 | |
| 78 | + cmp r3, #MAX_LOOP_COUNT | |
| 79 | + bne while_ack_0 | |
| 80 | + | |
| 81 | +ack_1: | |
| 82 | + mov r1, r3 | |
| 83 | + | |
| 84 | + /* | |
| 85 | + * Execute an ISB instruction to ensure that all of the | |
| 86 | + * CP15 register changes have been committed. | |
| 87 | + */ | |
| 88 | + isb | |
| 89 | + | |
| 90 | + /* | |
| 91 | + * Execute a barrier instruction to ensure that all cache, | |
| 92 | + * TLB and branch predictor maintenance operations issued | |
| 93 | + * by any CPU in the cluster have completed. | |
| 94 | + */ | |
| 95 | + dsb | |
| 96 | + dmb | |
| 97 | + | |
| 98 | + wfi | |
| 99 | + | |
| 100 | + /* Disable self-refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 0 */ | |
| 101 | + ldr r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR] | |
| 102 | + bic r2, r2, #SELFRSHREQ_MASK | |
| 103 | + str r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR] | |
| 104 | + | |
| 105 | + /* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 0 or hit max loops */ | |
| 106 | + mov r3, #0 | |
| 107 | +while_ack_1: | |
| 108 | + ldr r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR] | |
| 109 | + and r2, r2, #SELFRFSHACK_MASK | |
| 110 | + cmp r2, #SELFRFSHACK_MASK | |
| 111 | + bne ack_0 | |
| 112 | + | |
| 113 | + add r3, #1 | |
| 114 | + cmp r3, #MAX_LOOP_COUNT | |
| 115 | + bne while_ack_1 | |
| 116 | + | |
| 117 | +ack_0: | |
| 118 | + /* | |
| 119 | + * Prepare return value: | |
| 120 | + * Shift loop count for exiting self refresh into upper 16 bits. | |
| 121 | + * Leave loop count for requesting self refresh in lower 16 bits. | |
| 122 | + */ | |
| 123 | + mov r3, r3, lsl #16 | |
| 124 | + add r1, r1, r3 | |
| 125 | + | |
| 126 | + /* Disable dynamic clock gating in the Power Control Register. */ | |
| 127 | + mrc p15, 0, r2, c15, c0, 0 | |
| 128 | + bic r2, r2, #1 | |
| 129 | + mcr p15, 0, r2, c15, c0, 0 | |
| 130 | + | |
| 131 | + mov r0, r1 @ return value | |
| 132 | + bx lr @ return | |
| 133 | + | |
| 134 | +ENDPROC(socfpga_sdram_self_refresh) | |
| 135 | +ENTRY(socfpga_sdram_self_refresh_sz) | |
| 136 | + .word . - socfpga_sdram_self_refresh | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | − * Copyright (C) 2012 Altera Corporation | |
| 2 | + * Copyright (C) 2012-2015 Altera Corporation | |
| 3 | 3 | * |
| 4 | 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | 5 | * it under the terms of the GNU General Public License as published by |
| @@ -27,43 +27,11 @@ · 21 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | #include "core.h" |
| 29 | 29 | |
| 30 | −void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE)); | |
| 31 | 30 | void __iomem *sys_manager_base_addr; |
| 32 | 31 | void __iomem *rst_manager_base_addr; |
| 32 | +void __iomem *sdr_ctl_base_addr; | |
| 33 | 33 | unsigned long socfpga_cpu1start_addr; |
| 34 | 34 | |
| 35 | −static struct map_desc scu_io_desc __initdata = { | |
| 36 | − .virtual = SOCFPGA_SCU_VIRT_BASE, | |
| 37 | − .pfn = 0, /* run-time */ | |
| 38 | − .length = SZ_8K, | |
| 39 | − .type = MT_DEVICE, | |
| 40 | −}; | |
| 41 | − | |
| 42 | −static struct map_desc uart_io_desc __initdata = { | |
| 43 | − .virtual = 0xfec02000, | |
| 44 | − .pfn = __phys_to_pfn(0xffc02000), | |
| 45 | − .length = SZ_8K, | |
| 46 | − .type = MT_DEVICE, | |
| 47 | −}; | |
| 48 | − | |
| 49 | −static void __init socfpga_scu_map_io(void) | |
| 50 | −{ | |
| 51 | − unsigned long base; | |
| 52 | − | |
| 53 | − /* Get SCU base */ | |
| 54 | − asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); | |
| 55 | − | |
| 56 | − scu_io_desc.pfn = __phys_to_pfn(base); | |
| 57 | − iotable_init(&scu_io_desc, 1); | |
| 58 | −} | |
| 59 | − | |
| 60 | −static void __init socfpga_map_io(void) | |
| 61 | −{ | |
| 62 | − socfpga_scu_map_io(); | |
| 63 | − iotable_init(&uart_io_desc, 1); | |
| 64 | − early_printk("Early printk initialized\n"); | |
| 65 | −} | |
| 66 | − | |
| 67 | 35 | void __init socfpga_sysmgr_init(void) |
| 68 | 36 | { |
| 69 | 37 | struct device_node *np; |
| @@ -82,6 +50,9 @@ void __init socfpga_sysmgr_init(void) · 12 unmodified lines | ||
| 82 | 50 | |
| 83 | 51 | np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); |
| 84 | 52 | rst_manager_base_addr = of_iomap(np, 0); |
| 53 | + | |
| 54 | + np = of_find_compatible_node(NULL, NULL, "altr,sdr-ctl"); | |
| 55 | + sdr_ctl_base_addr = of_iomap(np, 0); | |
| 85 | 56 | } |
| 86 | 57 | |
| 87 | 58 | static void __init socfpga_init_irq(void) |
| @@ -111,8 +82,6 @@ static const char *altera_dt_match[] = { · 23 unmodified lines | ||
| 111 | 82 | DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA") |
| 112 | 83 | .l2c_aux_val = 0, |
| 113 | 84 | .l2c_aux_mask = ~0, |
| 114 | − .smp = smp_ops(socfpga_smp_ops), | |
| 115 | − .map_io = socfpga_map_io, | |
| 116 | 85 | .init_irq = socfpga_init_irq, |
| 117 | 86 | .restart = socfpga_cyclone5_restart, |
| 118 | 87 | .dt_compat = altera_dt_match, |
| @@ -0,0 +1 @@ | ||
| 1 | +obj-y += board-dt.o | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +# Empty file waiting for deletion once Makefile.boot isn't needed any more. | |
| 2 | +# Patch waits for application at | |
| 3 | +# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 . | |
| @@ -0,0 +1,19 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) Maxime Coquelin 2015 | |
| 3 | + * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> | |
| 4 | + * License terms: GNU General Public License (GPL), version 2 | |
| 5 | + */ | |
| 6 | + | |
| 7 | +#include <linux/kernel.h> | |
| 8 | +#include <asm/v7m.h> | |
| 9 | +#include <asm/mach/arch.h> | |
| 10 | + | |
| 11 | +static const char *const stm32_compat[] __initconst = { | |
| 12 | + "st,stm32f429", | |
| 13 | + NULL | |
| 14 | +}; | |
| 15 | + | |
| 16 | +DT_MACHINE_START(STM32DT, "STM32 (Device Tree Support)") | |
| 17 | + .dt_compat = stm32_compat, | |
| 18 | + .restart = armv7m_restart, | |
| 19 | +MACHINE_END | |
| @@ -121,3 +121,72 @@ static struct smp_operations sun6i_smp_ops __initdata = { · 120 unmodified lines | ||
| 121 | 121 | .smp_boot_secondary = sun6i_smp_boot_secondary, |
| 122 | 122 | }; |
| 123 | 123 | CPU_METHOD_OF_DECLARE(sun6i_a31_smp, "allwinner,sun6i-a31", &sun6i_smp_ops); |
| 124 | + | |
| 125 | +static void __init sun8i_smp_prepare_cpus(unsigned int max_cpus) | |
| 126 | +{ | |
| 127 | + struct device_node *node; | |
| 128 | + | |
| 129 | + node = of_find_compatible_node(NULL, NULL, "allwinner,sun8i-a23-prcm"); | |
| 130 | + if (!node) { | |
| 131 | + pr_err("Missing A23 PRCM node in the device tree\n"); | |
| 132 | + return; | |
| 133 | + } | |
| 134 | + | |
| 135 | + prcm_membase = of_iomap(node, 0); | |
| 136 | + if (!prcm_membase) { | |
| 137 | + pr_err("Couldn't map A23 PRCM registers\n"); | |
| 138 | + return; | |
| 139 | + } | |
| 140 | + | |
| 141 | + node = of_find_compatible_node(NULL, NULL, | |
| 142 | + "allwinner,sun8i-a23-cpuconfig"); | |
| 143 | + if (!node) { | |
| 144 | + pr_err("Missing A23 CPU config node in the device tree\n"); | |
| 145 | + return; | |
| 146 | + } | |
| 147 | + | |
| 148 | + cpucfg_membase = of_iomap(node, 0); | |
| 149 | + if (!cpucfg_membase) | |
| 150 | + pr_err("Couldn't map A23 CPU config registers\n"); | |
| 151 | + | |
| 152 | +} | |
| 153 | + | |
| 154 | +static int sun8i_smp_boot_secondary(unsigned int cpu, | |
| 155 | + struct task_struct *idle) | |
| 156 | +{ | |
| 157 | + u32 reg; | |
| 158 | + | |
| 159 | + if (!(prcm_membase && cpucfg_membase)) | |
| 160 | + return -EFAULT; | |
| 161 | + | |
| 162 | + spin_lock(&cpu_lock); | |
| 163 | + | |
| 164 | + /* Set CPU boot address */ | |
| 165 | + writel(virt_to_phys(secondary_startup), | |
| 166 | + cpucfg_membase + CPUCFG_PRIVATE0_REG); | |
| 167 | + | |
| 168 | + /* Assert the CPU core in reset */ | |
| 169 | + writel(0, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu)); | |
| 170 | + | |
| 171 | + /* Assert the L1 cache in reset */ | |
| 172 | + reg = readl(cpucfg_membase + CPUCFG_GEN_CTRL_REG); | |
| 173 | + writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_GEN_CTRL_REG); | |
| 174 | + | |
| 175 | + /* Clear CPU power-off gating */ | |
| 176 | + reg = readl(prcm_membase + PRCM_CPU_PWROFF_REG); | |
| 177 | + writel(reg & ~BIT(cpu), prcm_membase + PRCM_CPU_PWROFF_REG); | |
| 178 | + mdelay(1); | |
| 179 | + | |
| 180 | + /* Deassert the CPU core reset */ | |
| 181 | + writel(3, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu)); | |
| 182 | + | |
| 183 | + spin_unlock(&cpu_lock); | |
| 184 | + | |
| 185 | + return 0; | |
| 186 | +} | |
| 187 | + | |
| 188 | +struct smp_operations sun8i_smp_ops __initdata = { | |
| 189 | + .smp_prepare_cpus = sun8i_smp_prepare_cpus, | |
| 190 | + .smp_boot_secondary = sun8i_smp_boot_secondary, | |
| 191 | +}; | |
| 192 | +CPU_METHOD_OF_DECLARE(sun8i_a23_smp, "allwinner,sun8i-a23", &sun8i_smp_ops); | |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include "iomap.h" |
| 35 | 35 | #include "irq.h" |
| 36 | 36 | #include "pm.h" |
| 37 | +#include "reset.h" | |
| 37 | 38 | #include "sleep.h" |
| 38 | 39 | |
| 39 | 40 | #ifdef CONFIG_PM_SLEEP |
| @@ -70,15 +71,13 @@ static struct cpuidle_driver tegra_idle_driver = { · 30 unmodified lines | ||
| 70 | 71 | |
| 71 | 72 | #ifdef CONFIG_PM_SLEEP |
| 72 | 73 | #ifdef CONFIG_SMP |
| 73 | −static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); | |
| 74 | − | |
| 75 | 74 | static int tegra20_reset_sleeping_cpu_1(void) |
| 76 | 75 | { |
| 77 | 76 | int ret = 0; |
| 78 | 77 | |
| 79 | 78 | tegra_pen_lock(); |
| 80 | 79 | |
| 81 | − if (readl(pmc + PMC_SCRATCH41) == CPU_RESETTABLE) | |
| 80 | + if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE) | |
| 82 | 81 | tegra20_cpu_shutdown(1); |
| 83 | 82 | else |
| 84 | 83 | ret = -EINVAL; |
| @@ -169,10 +169,10 @@ after_errata: · 168 unmodified lines | ||
| 169 | 169 | cmp r6, #TEGRA20 |
| 170 | 170 | bne 1f |
| 171 | 171 | /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ |
| 172 | − mov32 r5, TEGRA_PMC_BASE | |
| 173 | − mov r0, #0 | |
| 172 | + mov32 r5, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET | |
| 173 | + mov r0, #CPU_NOT_RESETTABLE | |
| 174 | 174 | cmp r10, #0 |
| 175 | − strne r0, [r5, #PMC_SCRATCH41] | |
| 175 | + strneb r0, [r5, #__tegra20_cpu1_resettable_status_offset] | |
| 176 | 176 | 1: |
| 177 | 177 | #endif |
| 178 | 178 | |
| @@ -281,6 +281,10 @@ __tegra_cpu_reset_handler_data: · 102 unmodified lines | ||
| 281 | 281 | .rept TEGRA_RESET_DATA_SIZE |
| 282 | 282 | .long 0 |
| 283 | 283 | .endr |
| 284 | + .globl __tegra20_cpu1_resettable_status_offset | |
| 285 | + .equ __tegra20_cpu1_resettable_status_offset, \ | |
| 286 | + . - __tegra_cpu_reset_handler_start | |
| 287 | + .byte 0 | |
| 284 | 288 | .align L1_CACHE_SHIFT |
| 285 | 289 | |
| 286 | 290 | ENTRY(__tegra_cpu_reset_handler_end) |
| @@ -35,6 +35,7 @@ extern unsigned long __tegra_cpu_reset_handler_data[TEGRA_RESET_DATA_SIZE]; · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | void __tegra_cpu_reset_handler_start(void); |
| 37 | 37 | void __tegra_cpu_reset_handler(void); |
| 38 | +void __tegra20_cpu1_resettable_status_offset(void); | |
| 38 | 39 | void __tegra_cpu_reset_handler_end(void); |
| 39 | 40 | |
| 40 | 41 | #ifdef CONFIG_PM_SLEEP |
| @@ -46,6 +47,9 @@ void __tegra_cpu_reset_handler_end(void); · 5 unmodified lines | ||
| 46 | 47 | (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \ |
| 47 | 48 | ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \ |
| 48 | 49 | (u32)__tegra_cpu_reset_handler_start))) |
| 50 | +#define tegra20_cpu1_resettable_status \ | |
| 51 | + (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \ | |
| 52 | + (u32)__tegra20_cpu1_resettable_status_offset)) | |
| 49 | 53 | #endif |
| 50 | 54 | |
| 51 | 55 | #define tegra_cpu_reset_handler_offset \ |
| @@ -97,9 +97,10 @@ ENDPROC(tegra20_hotplug_shutdown) · 96 unmodified lines | ||
| 97 | 97 | ENTRY(tegra20_cpu_shutdown) |
| 98 | 98 | cmp r0, #0 |
| 99 | 99 | reteq lr @ must not be called for CPU 0 |
| 100 | − mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | |
| 100 | + mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT | |
| 101 | + ldr r2, =__tegra20_cpu1_resettable_status_offset | |
| 101 | 102 | mov r12, #CPU_RESETTABLE |
| 102 | − str r12, [r1] | |
| 103 | + strb r12, [r1, r2] | |
| 103 | 104 | |
| 104 | 105 | cpu_to_halt_reg r1, r0 |
| 105 | 106 | ldr r3, =TEGRA_FLOW_CTRL_VIRT |
| @@ -182,38 +183,41 @@ ENDPROC(tegra_pen_unlock) · 76 unmodified lines | ||
| 182 | 183 | /* |
| 183 | 184 | * tegra20_cpu_clear_resettable(void) |
| 184 | 185 | * |
| 185 | − * Called to clear the "resettable soon" flag in PMC_SCRATCH41 when | |
| 186 | + * Called to clear the "resettable soon" flag in IRAM variable when | |
| 186 | 187 | * it is expected that the secondary CPU will be idle soon. |
| 187 | 188 | */ |
| 188 | 189 | ENTRY(tegra20_cpu_clear_resettable) |
| 189 | − mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | |
| 190 | + mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT | |
| 191 | + ldr r2, =__tegra20_cpu1_resettable_status_offset | |
| 190 | 192 | mov r12, #CPU_NOT_RESETTABLE |
| 191 | − str r12, [r1] | |
| 193 | + strb r12, [r1, r2] | |
| 192 | 194 | ret lr |
| 193 | 195 | ENDPROC(tegra20_cpu_clear_resettable) |
| 194 | 196 | |
| 195 | 197 | /* |
| 196 | 198 | * tegra20_cpu_set_resettable_soon(void) |
| 197 | 199 | * |
| 198 | − * Called to set the "resettable soon" flag in PMC_SCRATCH41 when | |
| 200 | + * Called to set the "resettable soon" flag in IRAM variable when | |
| 199 | 201 | * it is expected that the secondary CPU will be idle soon. |
| 200 | 202 | */ |
| 201 | 203 | ENTRY(tegra20_cpu_set_resettable_soon) |
| 202 | − mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | |
| 204 | + mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT | |
| 205 | + ldr r2, =__tegra20_cpu1_resettable_status_offset | |
| 203 | 206 | mov r12, #CPU_RESETTABLE_SOON |
| 204 | − str r12, [r1] | |
| 207 | + strb r12, [r1, r2] | |
| 205 | 208 | ret lr |
| 206 | 209 | ENDPROC(tegra20_cpu_set_resettable_soon) |
| 207 | 210 | |
| 208 | 211 | /* |
| 209 | 212 | * tegra20_cpu_is_resettable_soon(void) |
| 210 | 213 | * |
| 211 | − * Returns true if the "resettable soon" flag in PMC_SCRATCH41 has been | |
| 214 | + * Returns true if the "resettable soon" flag in IRAM variable has been | |
| 212 | 215 | * set because it is expected that the secondary CPU will be idle soon. |
| 213 | 216 | */ |
| 214 | 217 | ENTRY(tegra20_cpu_is_resettable_soon) |
| 215 | − mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | |
| 216 | − ldr r12, [r1] | |
| 218 | + mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT | |
| 219 | + ldr r2, =__tegra20_cpu1_resettable_status_offset | |
| 220 | + ldrb r12, [r1, r2] | |
| 217 | 221 | cmp r12, #CPU_RESETTABLE_SOON |
| 218 | 222 | moveq r0, #1 |
| 219 | 223 | movne r0, #0 |
| @@ -256,9 +260,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish) · 36 unmodified lines | ||
| 256 | 260 | mov r0, #TEGRA_FLUSH_CACHE_LOUIS |
| 257 | 261 | bl tegra_disable_clean_inv_dcache |
| 258 | 262 | |
| 259 | − mov32 r0, TEGRA_PMC_VIRT + PMC_SCRATCH41 | |
| 263 | + mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT | |
| 264 | + ldr r4, =__tegra20_cpu1_resettable_status_offset | |
| 260 | 265 | mov r3, #CPU_RESETTABLE |
| 261 | − str r3, [r0] | |
| 266 | + strb r3, [r0, r4] | |
| 262 | 267 | |
| 263 | 268 | bl tegra_cpu_do_idle |
| 264 | 269 | |
| @@ -274,10 +279,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish) · 9 unmodified lines | ||
| 274 | 279 | |
| 275 | 280 | bl tegra_pen_lock |
| 276 | 281 | |
| 277 | − mov32 r3, TEGRA_PMC_VIRT | |
| 278 | − add r0, r3, #PMC_SCRATCH41 | |
| 282 | + mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT | |
| 283 | + ldr r4, =__tegra20_cpu1_resettable_status_offset | |
| 279 | 284 | mov r3, #CPU_NOT_RESETTABLE |
| 280 | − str r3, [r0] | |
| 285 | + strb r3, [r0, r4] | |
| 281 | 286 | |
| 282 | 287 | bl tegra_pen_unlock |
| 283 | 288 | |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #define __MACH_TEGRA_SLEEP_H |
| 19 | 19 | |
| 20 | 20 | #include "iomap.h" |
| 21 | +#include "irammap.h" | |
| 21 | 22 | |
| 22 | 23 | #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \ |
| 23 | 24 | + IO_CPU_VIRT) |
| @@ -29,6 +30,9 @@ · 5 unmodified lines | ||
| 29 | 30 | + IO_APB_VIRT) |
| 30 | 31 | #define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT) |
| 31 | 32 | |
| 33 | +#define TEGRA_IRAM_RESET_BASE_VIRT (IO_IRAM_VIRT + \ | |
| 34 | + TEGRA_IRAM_RESET_HANDLER_OFFSET) | |
| 35 | + | |
| 32 | 36 | /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */ |
| 33 | 37 | #define PMC_SCRATCH37 0x130 |
| 34 | 38 | #define PMC_SCRATCH38 0x134 |
| @@ -163,6 +163,5 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)") · 162 unmodified lines | ||
| 163 | 163 | .init_irq = tegra_dt_init_irq, |
| 164 | 164 | .init_machine = tegra_dt_init, |
| 165 | 165 | .init_late = tegra_dt_init_late, |
| 166 | − .restart = tegra_pmc_restart, | |
| 167 | 166 | .dt_compat = tegra_dt_board_compat, |
| 168 | 167 | MACHINE_END |
| @@ -0,0 +1,11 @@ | ||
| 1 | +config ARCH_UNIPHIER | |
| 2 | + bool "Socionext UniPhier SoCs" | |
| 3 | + depends on ARCH_MULTI_V7 | |
| 4 | + select ARM_AMBA | |
| 5 | + select ARM_GLOBAL_TIMER | |
| 6 | + select ARM_GIC | |
| 7 | + select HAVE_ARM_SCU | |
| 8 | + select HAVE_ARM_TWD if SMP | |
| 9 | + help | |
| 10 | + Support for UniPhier SoC family developed by Socionext Inc. | |
| 11 | + (formerly, System LSI Business Division of Panasonic Corporation) | |
| @@ -0,0 +1,2 @@ | ||
| 1 | +obj-y := uniphier.o | |
| 2 | +obj-$(CONFIG_SMP) += platsmp.o | |
| @@ -0,0 +1,90 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.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 | + | |
| 15 | +#include <linux/sizes.h> | |
| 16 | +#include <linux/compiler.h> | |
| 17 | +#include <linux/init.h> | |
| 18 | +#include <linux/io.h> | |
| 19 | +#include <linux/regmap.h> | |
| 20 | +#include <linux/mfd/syscon.h> | |
| 21 | +#include <asm/smp.h> | |
| 22 | +#include <asm/smp_scu.h> | |
| 23 | + | |
| 24 | +static struct regmap *sbcm_regmap; | |
| 25 | + | |
| 26 | +static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus) | |
| 27 | +{ | |
| 28 | + static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; | |
| 29 | + unsigned long scu_base_phys = 0; | |
| 30 | + void __iomem *scu_base; | |
| 31 | + | |
| 32 | + sbcm_regmap = syscon_regmap_lookup_by_compatible( | |
| 33 | + "socionext,uniphier-system-bus-controller-misc"); | |
| 34 | + if (IS_ERR(sbcm_regmap)) { | |
| 35 | + pr_err("failed to regmap system-bus-controller-misc\n"); | |
| 36 | + goto err; | |
| 37 | + } | |
| 38 | + | |
| 39 | + if (scu_a9_has_base()) | |
| 40 | + scu_base_phys = scu_a9_get_base(); | |
| 41 | + | |
| 42 | + if (!scu_base_phys) { | |
| 43 | + pr_err("failed to get scu base\n"); | |
| 44 | + goto err; | |
| 45 | + } | |
| 46 | + | |
| 47 | + scu_base = ioremap(scu_base_phys, SZ_128); | |
| 48 | + if (!scu_base) { | |
| 49 | + pr_err("failed to remap scu base (0x%08lx)\n", scu_base_phys); | |
| 50 | + goto err; | |
| 51 | + } | |
| 52 | + | |
| 53 | + scu_enable(scu_base); | |
| 54 | + iounmap(scu_base); | |
| 55 | + | |
| 56 | + return; | |
| 57 | +err: | |
| 58 | + pr_warn("disabling SMP\n"); | |
| 59 | + init_cpu_present(&only_cpu_0); | |
| 60 | + sbcm_regmap = NULL; | |
| 61 | +} | |
| 62 | + | |
| 63 | +static void __naked uniphier_secondary_startup(void) | |
| 64 | +{ | |
| 65 | + asm("bl v7_invalidate_l1\n" | |
| 66 | + "b secondary_startup\n"); | |
| 67 | +}; | |
| 68 | + | |
| 69 | +static int uniphier_boot_secondary(unsigned int cpu, | |
| 70 | + struct task_struct *idle) | |
| 71 | +{ | |
| 72 | + int ret; | |
| 73 | + | |
| 74 | + if (!sbcm_regmap) | |
| 75 | + return -ENODEV; | |
| 76 | + | |
| 77 | + ret = regmap_write(sbcm_regmap, 0x1208, | |
| 78 | + virt_to_phys(uniphier_secondary_startup)); | |
| 79 | + if (!ret) | |
| 80 | + asm("sev"); /* wake up secondary CPU */ | |
| 81 | + | |
| 82 | + return ret; | |
| 83 | +} | |
| 84 | + | |
| 85 | +struct smp_operations uniphier_smp_ops __initdata = { | |
| 86 | + .smp_prepare_cpus = uniphier_smp_prepare_cpus, | |
| 87 | + .smp_boot_secondary = uniphier_boot_secondary, | |
| 88 | +}; | |
| 89 | +CPU_METHOD_OF_DECLARE(uniphier_smp, "socionext,uniphier-smp", | |
| 90 | + &uniphier_smp_ops); | |
| @@ -0,0 +1,30 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.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 | + | |
| 15 | +#include <asm/mach/arch.h> | |
| 16 | + | |
| 17 | +static const char * const uniphier_dt_compat[] __initconst = { | |
| 18 | + "socionext,ph1-sld3", | |
| 19 | + "socionext,ph1-ld4", | |
| 20 | + "socionext,ph1-pro4", | |
| 21 | + "socionext,ph1-sld8", | |
| 22 | + "socionext,ph1-pro5", | |
| 23 | + "socionext,proxstream2", | |
| 24 | + "socionext,ph1-ld6b", | |
| 25 | + NULL, | |
| 26 | +}; | |
| 27 | + | |
| 28 | +DT_MACHINE_START(UNIPHIER, "Socionext UniPhier") | |
| 29 | + .dt_compat = uniphier_dt_compat, | |
| 30 | +MACHINE_END | |
| @@ -0,0 +1,18 @@ | ||
| 1 | +menuconfig ARCH_ZX | |
| 2 | + bool "ZTE ZX family" if ARCH_MULTI_V7 | |
| 3 | + help | |
| 4 | + Support for ZTE ZX-based family of processors. TV | |
| 5 | + set-top-box processor is supported. More will be | |
| 6 | + added soon. | |
| 7 | + | |
| 8 | +if ARCH_ZX | |
| 9 | + | |
| 10 | +config SOC_ZX296702 | |
| 11 | + def_bool y | |
| 12 | + select ARM_GIC | |
| 13 | + select ARM_GLOBAL_TIMER | |
| 14 | + select HAVE_ARM_SCU if SMP | |
| 15 | + select HAVE_ARM_TWD if SMP | |
| 16 | + help | |
| 17 | + Support for ZTE ZX296702 SoC which is a dual core CortexA9MP | |
| 18 | +endif | |
| @@ -0,0 +1,2 @@ | ||
| 1 | +obj-$(CONFIG_SOC_ZX296702) += zx296702.o | |
| 2 | +obj-$(CONFIG_SMP) += headsmp.o platsmp.o | |
| @@ -0,0 +1,19 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2014 Linaro Ltd. | |
| 3 | + * Copyright (C) 2014 ZTE Corporation. | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#ifndef __MACH_ZX_CORE_H | |
| 11 | +#define __MACH_ZX_CORE_H | |
| 12 | + | |
| 13 | +extern void zx_resume_jump(void); | |
| 14 | +extern size_t zx_suspend_iram_sz; | |
| 15 | +extern unsigned long zx_secondary_startup_pa; | |
| 16 | + | |
| 17 | +void zx_secondary_startup(void); | |
| 18 | + | |
| 19 | +#endif /* __MACH_ZX_CORE_H */ | |
| @@ -0,0 +1,33 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2014 Linaro Ltd. | |
| 3 | + * Copyright (C) 2014 ZTE Corporation. | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/linkage.h> | |
| 11 | + | |
| 12 | + .align 3 | |
| 13 | + .arm | |
| 14 | + | |
| 15 | +/* It runs from physical address */ | |
| 16 | +ENTRY(zx_resume_jump) | |
| 17 | + adr r1, zx_secondary_startup_pa | |
| 18 | + ldr r0, [r1] | |
| 19 | + bx r0 | |
| 20 | +ENDPROC(zx_resume_jump) | |
| 21 | + | |
| 22 | +ENTRY(zx_secondary_startup_pa) | |
| 23 | + .word zx_secondary_startup_pa | |
| 24 | + | |
| 25 | +ENTRY(zx_suspend_iram_sz) | |
| 26 | + .word . - zx_resume_jump | |
| 27 | +ENDPROC(zx_secondary_startup_pa) | |
| 28 | + | |
| 29 | + | |
| 30 | +ENTRY(zx_secondary_startup) | |
| 31 | + bl v7_invalidate_l1 | |
| 32 | + b secondary_startup | |
| 33 | +ENDPROC(zx_secondary_startup) | |
| @@ -0,0 +1,189 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2014 Linaro Ltd. | |
| 3 | + * Copyright (C) 2014 ZTE Corporation. | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/delay.h> | |
| 11 | +#include <linux/errno.h> | |
| 12 | +#include <linux/init.h> | |
| 13 | +#include <linux/io.h> | |
| 14 | +#include <linux/jiffies.h> | |
| 15 | +#include <linux/of.h> | |
| 16 | +#include <linux/of_address.h> | |
| 17 | +#include <linux/smp.h> | |
| 18 | + | |
| 19 | +#include <asm/cacheflush.h> | |
| 20 | +#include <asm/cp15.h> | |
| 21 | +#include <asm/fncpy.h> | |
| 22 | +#include <asm/proc-fns.h> | |
| 23 | +#include <asm/smp_scu.h> | |
| 24 | +#include <asm/smp_plat.h> | |
| 25 | + | |
| 26 | +#include "core.h" | |
| 27 | + | |
| 28 | +#define AON_SYS_CTRL_RESERVED1 0xa8 | |
| 29 | + | |
| 30 | +#define BUS_MATRIX_REMAP_CONFIG 0x00 | |
| 31 | + | |
| 32 | +#define PCU_CPU0_CTRL 0x00 | |
| 33 | +#define PCU_CPU1_CTRL 0x04 | |
| 34 | +#define PCU_CPU1_ST 0x0c | |
| 35 | +#define PCU_GLOBAL_CTRL 0x14 | |
| 36 | +#define PCU_EXPEND_CONTROL 0x34 | |
| 37 | + | |
| 38 | +#define ZX_IRAM_BASE 0x00200000 | |
| 39 | + | |
| 40 | +static void __iomem *pcu_base; | |
| 41 | +static void __iomem *matrix_base; | |
| 42 | +static void __iomem *scu_base; | |
| 43 | + | |
| 44 | +void __init zx_smp_prepare_cpus(unsigned int max_cpus) | |
| 45 | +{ | |
| 46 | + struct device_node *np; | |
| 47 | + unsigned long base = 0; | |
| 48 | + void __iomem *aonsysctrl_base; | |
| 49 | + void __iomem *sys_iram; | |
| 50 | + | |
| 51 | + base = scu_a9_get_base(); | |
| 52 | + scu_base = ioremap(base, SZ_256); | |
| 53 | + if (!scu_base) { | |
| 54 | + pr_err("%s: failed to map scu\n", __func__); | |
| 55 | + return; | |
| 56 | + } | |
| 57 | + | |
| 58 | + scu_enable(scu_base); | |
| 59 | + | |
| 60 | + np = of_find_compatible_node(NULL, NULL, "zte,sysctrl"); | |
| 61 | + if (!np) { | |
| 62 | + pr_err("%s: failed to find sysctrl node\n", __func__); | |
| 63 | + return; | |
| 64 | + } | |
| 65 | + | |
| 66 | + aonsysctrl_base = of_iomap(np, 0); | |
| 67 | + if (!aonsysctrl_base) { | |
| 68 | + pr_err("%s: failed to map aonsysctrl\n", __func__); | |
| 69 | + of_node_put(np); | |
| 70 | + return; | |
| 71 | + } | |
| 72 | + | |
| 73 | + /* | |
| 74 | + * Write the address of secondary startup into the | |
| 75 | + * system-wide flags register. The BootMonitor waits | |
| 76 | + * until it receives a soft interrupt, and then the | |
| 77 | + * secondary CPU branches to this address. | |
| 78 | + */ | |
| 79 | + __raw_writel(virt_to_phys(zx_secondary_startup), | |
| 80 | + aonsysctrl_base + AON_SYS_CTRL_RESERVED1); | |
| 81 | + | |
| 82 | + iounmap(aonsysctrl_base); | |
| 83 | + of_node_put(np); | |
| 84 | + | |
| 85 | + np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu"); | |
| 86 | + pcu_base = of_iomap(np, 0); | |
| 87 | + of_node_put(np); | |
| 88 | + WARN_ON(!pcu_base); | |
| 89 | + | |
| 90 | + np = of_find_compatible_node(NULL, NULL, "zte,zx-bus-matrix"); | |
| 91 | + matrix_base = of_iomap(np, 0); | |
| 92 | + of_node_put(np); | |
| 93 | + WARN_ON(!matrix_base); | |
| 94 | + | |
| 95 | + /* Map the first 4 KB IRAM for suspend usage */ | |
| 96 | + sys_iram = __arm_ioremap_exec(ZX_IRAM_BASE, PAGE_SIZE, false); | |
| 97 | + zx_secondary_startup_pa = virt_to_phys(zx_secondary_startup); | |
| 98 | + fncpy(sys_iram, &zx_resume_jump, zx_suspend_iram_sz); | |
| 99 | +} | |
| 100 | + | |
| 101 | +static int zx_boot_secondary(unsigned int cpu, struct task_struct *idle) | |
| 102 | +{ | |
| 103 | + static bool first_boot = true; | |
| 104 | + | |
| 105 | + if (first_boot) { | |
| 106 | + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); | |
| 107 | + first_boot = false; | |
| 108 | + return 0; | |
| 109 | + } | |
| 110 | + | |
| 111 | + /* Swap the base address mapping between IRAM and IROM */ | |
| 112 | + writel_relaxed(0x1, matrix_base + BUS_MATRIX_REMAP_CONFIG); | |
| 113 | + | |
| 114 | + /* Power on CPU1 */ | |
| 115 | + writel_relaxed(0x0, pcu_base + PCU_CPU1_CTRL); | |
| 116 | + | |
| 117 | + /* Wait for power on ack */ | |
| 118 | + while (readl_relaxed(pcu_base + PCU_CPU1_ST) & 0x4) | |
| 119 | + cpu_relax(); | |
| 120 | + | |
| 121 | + /* Swap back the mapping of IRAM and IROM */ | |
| 122 | + writel_relaxed(0x0, matrix_base + BUS_MATRIX_REMAP_CONFIG); | |
| 123 | + | |
| 124 | + return 0; | |
| 125 | +} | |
| 126 | + | |
| 127 | +#ifdef CONFIG_HOTPLUG_CPU | |
| 128 | +static inline void cpu_enter_lowpower(void) | |
| 129 | +{ | |
| 130 | + unsigned int v; | |
| 131 | + | |
| 132 | + asm volatile( | |
| 133 | + "mcr p15, 0, %1, c7, c5, 0\n" | |
| 134 | + " mcr p15, 0, %1, c7, c10, 4\n" | |
| 135 | + /* | |
| 136 | + * Turn off coherency | |
| 137 | + */ | |
| 138 | + " mrc p15, 0, %0, c1, c0, 1\n" | |
| 139 | + " bic %0, %0, %3\n" | |
| 140 | + " mcr p15, 0, %0, c1, c0, 1\n" | |
| 141 | + " mrc p15, 0, %0, c1, c0, 0\n" | |
| 142 | + " bic %0, %0, %2\n" | |
| 143 | + " mcr p15, 0, %0, c1, c0, 0\n" | |
| 144 | + : "=&r" (v) | |
| 145 | + : "r" (0), "Ir" (CR_C), "Ir" (0x40) | |
| 146 | + : "cc"); | |
| 147 | +} | |
| 148 | + | |
| 149 | +static int zx_cpu_kill(unsigned int cpu) | |
| 150 | +{ | |
| 151 | + unsigned long timeout = jiffies + msecs_to_jiffies(2000); | |
| 152 | + | |
| 153 | + writel_relaxed(0x2, pcu_base + PCU_CPU1_CTRL); | |
| 154 | + | |
| 155 | + while ((readl_relaxed(pcu_base + PCU_CPU1_ST) & 0x3) != 0x0) { | |
| 156 | + if (time_after(jiffies, timeout)) { | |
| 157 | + pr_err("*** cpu1 poweroff timeout\n"); | |
| 158 | + break; | |
| 159 | + } | |
| 160 | + } | |
| 161 | + return 1; | |
| 162 | +} | |
| 163 | + | |
| 164 | +static void zx_cpu_die(unsigned int cpu) | |
| 165 | +{ | |
| 166 | + scu_power_mode(scu_base, SCU_PM_POWEROFF); | |
| 167 | + cpu_enter_lowpower(); | |
| 168 | + | |
| 169 | + while (1) | |
| 170 | + cpu_do_idle(); | |
| 171 | +} | |
| 172 | +#endif | |
| 173 | + | |
| 174 | +static void zx_secondary_init(unsigned int cpu) | |
| 175 | +{ | |
| 176 | + scu_power_mode(scu_base, SCU_PM_NORMAL); | |
| 177 | +} | |
| 178 | + | |
| 179 | +struct smp_operations zx_smp_ops __initdata = { | |
| 180 | + .smp_prepare_cpus = zx_smp_prepare_cpus, | |
| 181 | + .smp_secondary_init = zx_secondary_init, | |
| 182 | + .smp_boot_secondary = zx_boot_secondary, | |
| 183 | +#ifdef CONFIG_HOTPLUG_CPU | |
| 184 | + .cpu_kill = zx_cpu_kill, | |
| 185 | + .cpu_die = zx_cpu_die, | |
| 186 | +#endif | |
| 187 | +}; | |
| 188 | + | |
| 189 | +CPU_METHOD_OF_DECLARE(zx_smp, "zte,zx296702-smp", &zx_smp_ops); | |
| @@ -0,0 +1,25 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2014 Linaro Ltd. | |
| 3 | + * Copyright (C) 2014 ZTE Corporation. | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <asm/mach/arch.h> | |
| 11 | +#include <asm/mach/map.h> | |
| 12 | + | |
| 13 | +#include <linux/of_address.h> | |
| 14 | +#include <linux/of_platform.h> | |
| 15 | + | |
| 16 | +static const char *zx296702_dt_compat[] __initconst = { | |
| 17 | + "zte,zx296702", | |
| 18 | + NULL, | |
| 19 | +}; | |
| 20 | + | |
| 21 | +DT_MACHINE_START(ZX, "ZTE ZX296702 (Device Tree)") | |
| 22 | + .dt_compat = zx296702_dt_compat, | |
| 23 | + .l2c_aux_val = 0, | |
| 24 | + .l2c_aux_mask = ~0, | |
| 25 | +MACHINE_END | |
| @@ -190,11 +190,6 @@ static void __init zynq_irq_init(void) · 189 unmodified lines | ||
| 190 | 190 | irqchip_init(); |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | −static void zynq_system_reset(enum reboot_mode mode, const char *cmd) | |
| 194 | −{ | |
| 195 | − zynq_slcr_system_reset(); | |
| 196 | −} | |
| 197 | − | |
| 198 | 193 | static const char * const zynq_dt_match[] = { |
| 199 | 194 | "xlnx,zynq-7000", |
| 200 | 195 | NULL |
| @@ -212,5 +207,4 @@ DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") · 11 unmodified lines | ||
| 212 | 207 | .init_time = zynq_timer_init, |
| 213 | 208 | .dt_compat = zynq_dt_match, |
| 214 | 209 | .reserve = zynq_memory_init, |
| 215 | − .restart = zynq_system_reset, | |
| 216 | 210 | MACHINE_END |
| @@ -19,7 +19,6 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | extern int zynq_slcr_init(void); |
| 21 | 21 | extern int zynq_early_slcr_init(void); |
| 22 | −extern void zynq_slcr_system_reset(void); | |
| 23 | 22 | extern void zynq_slcr_cpu_stop(int cpu); |
| 24 | 23 | extern void zynq_slcr_cpu_start(int cpu); |
| 25 | 24 | extern bool zynq_slcr_cpu_state_read(int cpu); |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | 17 | #include <linux/io.h> |
| 18 | +#include <linux/reboot.h> | |
| 18 | 19 | #include <linux/mfd/syscon.h> |
| 19 | 20 | #include <linux/of_address.h> |
| 20 | 21 | #include <linux/regmap.h> |
| @@ -92,19 +93,20 @@ u32 zynq_slcr_get_device_id(void) · 71 unmodified lines | ||
| 92 | 93 | } |
| 93 | 94 | |
| 94 | 95 | /** |
| 95 | − * zynq_slcr_system_reset - Reset the entire system. | |
| 96 | + * zynq_slcr_system_restart - Restart the entire system. | |
| 97 | + * | |
| 98 | + * @nb: Pointer to restart notifier block (unused) | |
| 99 | + * @action: Reboot mode (unused) | |
| 100 | + * @data: Restart handler private data (unused) | |
| 101 | + * | |
| 102 | + * Return: 0 always | |
| 96 | 103 | */ |
| 97 | −void zynq_slcr_system_reset(void) | |
| 104 | +static | |
| 105 | +int zynq_slcr_system_restart(struct notifier_block *nb, | |
| 106 | + unsigned long action, void *data) | |
| 98 | 107 | { |
| 99 | 108 | u32 reboot; |
| 100 | 109 | |
| 101 | − /* | |
| 102 | − * Unlock the SLCR then reset the system. | |
| 103 | − * Note that this seems to require raw i/o | |
| 104 | − * functions or there's a lockup? | |
| 105 | − */ | |
| 106 | − zynq_slcr_unlock(); | |
| 107 | − | |
| 108 | 110 | /* |
| 109 | 111 | * Clear 0x0F000000 bits of reboot status register to workaround |
| 110 | 112 | * the FSBL not loading the bitstream after soft-reboot |
| @@ -113,8 +115,14 @@ void zynq_slcr_system_reset(void) · 2 unmodified lines | ||
| 113 | 115 | zynq_slcr_read(&reboot, SLCR_REBOOT_STATUS_OFFSET); |
| 114 | 116 | zynq_slcr_write(reboot & 0xF0FFFFFF, SLCR_REBOOT_STATUS_OFFSET); |
| 115 | 117 | zynq_slcr_write(1, SLCR_PS_RST_CTRL_OFFSET); |
| 118 | + return 0; | |
| 116 | 119 | } |
| 117 | 120 | |
| 121 | +static struct notifier_block zynq_slcr_restart_nb = { | |
| 122 | + .notifier_call = zynq_slcr_system_restart, | |
| 123 | + .priority = 192, | |
| 124 | +}; | |
| 125 | + | |
| 118 | 126 | /** |
| 119 | 127 | * zynq_slcr_cpu_start - Start cpu |
| 120 | 128 | * @cpu: cpu number |
| @@ -219,6 +227,8 @@ int __init zynq_early_slcr_init(void) · 98 unmodified lines | ||
| 219 | 227 | /* unlock the SLCR so that registers can be changed */ |
| 220 | 228 | zynq_slcr_unlock(); |
| 221 | 229 | |
| 230 | + register_restart_handler(&zynq_slcr_restart_nb); | |
| 231 | + | |
| 222 | 232 | pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); |
| 223 | 233 | |
| 224 | 234 | of_node_put(np); |
| @@ -38,6 +38,10 @@ · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | #include <linux/omap-dma.h> |
| 40 | 40 | |
| 41 | +#ifdef CONFIG_ARCH_OMAP1 | |
| 42 | +#include <mach/soc.h> | |
| 43 | +#endif | |
| 44 | + | |
| 41 | 45 | /* |
| 42 | 46 | * MAX_LOGICAL_DMA_CH_COUNT: the maximum number of logical DMA |
| 43 | 47 | * channels that an instance of the SDMA IP block can support. Used |
| @@ -389,7 +389,7 @@ static int s3c_adc_probe(struct platform_device *pdev) · 388 unmodified lines | ||
| 389 | 389 | if (ret) |
| 390 | 390 | return ret; |
| 391 | 391 | |
| 392 | − clk_enable(adc->clk); | |
| 392 | + clk_prepare_enable(adc->clk); | |
| 393 | 393 | |
| 394 | 394 | tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; |
| 395 | 395 | |
| @@ -413,7 +413,7 @@ static int s3c_adc_remove(struct platform_device *pdev) · 17 unmodified lines | ||
| 413 | 413 | { |
| 414 | 414 | struct adc_device *adc = platform_get_drvdata(pdev); |
| 415 | 415 | |
| 416 | − clk_disable(adc->clk); | |
| 416 | + clk_disable_unprepare(adc->clk); | |
| 417 | 417 | regulator_disable(adc->vdd); |
| 418 | 418 | |
| 419 | 419 | return 0; |
| @@ -475,7 +475,7 @@ static int s3c_adc_resume(struct device *dev) · 55 unmodified lines | ||
| 475 | 475 | #define s3c_adc_resume NULL |
| 476 | 476 | #endif |
| 477 | 477 | |
| 478 | −static struct platform_device_id s3c_adc_driver_ids[] = { | |
| 478 | +static const struct platform_device_id s3c_adc_driver_ids[] = { | |
| 479 | 479 | { |
| 480 | 480 | .name = "s3c24xx-adc", |
| 481 | 481 | .driver_data = TYPE_ADCV1, |
| @@ -445,6 +445,19 @@ static void vfp_enable(void *unused) · 444 unmodified lines | ||
| 445 | 445 | set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11)); |
| 446 | 446 | } |
| 447 | 447 | |
| 448 | +/* Called by platforms on which we want to disable VFP because it may not be | |
| 449 | + * present on all CPUs within a SMP complex. Needs to be called prior to | |
| 450 | + * vfp_init(). | |
| 451 | + */ | |
| 452 | +void vfp_disable(void) | |
| 453 | +{ | |
| 454 | + if (VFP_arch) { | |
| 455 | + pr_debug("%s: should be called prior to vfp_init\n", __func__); | |
| 456 | + return; | |
| 457 | + } | |
| 458 | + VFP_arch = 1; | |
| 459 | +} | |
| 460 | + | |
| 448 | 461 | #ifdef CONFIG_CPU_PM |
| 449 | 462 | static int vfp_pm_suspend(void) |
| 450 | 463 | { |
| @@ -184,6 +184,11 @@ config ARCH_FSL_LS2085A · 183 unmodified lines | ||
| 184 | 184 | help |
| 185 | 185 | This enables support for Freescale LS2085A SOC. |
| 186 | 186 | |
| 187 | +config ARCH_HISI | |
| 188 | + bool "Hisilicon SoC Family" | |
| 189 | + help | |
| 190 | + This enables support for Hisilicon ARMv8 SoC family | |
| 191 | + | |
| 187 | 192 | config ARCH_MEDIATEK |
| 188 | 193 | bool "Mediatek MT65xx & MT81xx ARMv8 SoC" |
| 189 | 194 | select ARM_GIC |
| @@ -33,6 +33,7 @@ CONFIG_MODULE_UNLOAD=y · 32 unmodified lines | ||
| 33 | 33 | # CONFIG_IOSCHED_DEADLINE is not set |
| 34 | 34 | CONFIG_ARCH_EXYNOS7=y |
| 35 | 35 | CONFIG_ARCH_FSL_LS2085A=y |
| 36 | +CONFIG_ARCH_HISI=y | |
| 36 | 37 | CONFIG_ARCH_MEDIATEK=y |
| 37 | 38 | CONFIG_ARCH_SEATTLE=y |
| 38 | 39 | CONFIG_ARCH_TEGRA=y |
| @@ -91,6 +91,7 @@ static const int gisb_offsets_bcm7445[] = { · 90 unmodified lines | ||
| 91 | 91 | struct brcmstb_gisb_arb_device { |
| 92 | 92 | void __iomem *base; |
| 93 | 93 | const int *gisb_offsets; |
| 94 | + bool big_endian; | |
| 94 | 95 | struct mutex lock; |
| 95 | 96 | struct list_head next; |
| 96 | 97 | u32 valid_mask; |
| @@ -108,7 +109,10 @@ static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg) · 11 unmodified lines | ||
| 108 | 109 | if (offset == -1) |
| 109 | 110 | return 1; |
| 110 | 111 | |
| 111 | − return ioread32(gdev->base + offset); | |
| 112 | + if (gdev->big_endian) | |
| 113 | + return ioread32be(gdev->base + offset); | |
| 114 | + else | |
| 115 | + return ioread32(gdev->base + offset); | |
| 112 | 116 | } |
| 113 | 117 | |
| 114 | 118 | static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg) |
| @@ -117,7 +121,11 @@ static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg) · 2 unmodified lines | ||
| 117 | 121 | |
| 118 | 122 | if (offset == -1) |
| 119 | 123 | return; |
| 120 | − iowrite32(val, gdev->base + reg); | |
| 124 | + | |
| 125 | + if (gdev->big_endian) | |
| 126 | + iowrite32be(val, gdev->base + reg); | |
| 127 | + else | |
| 128 | + iowrite32(val, gdev->base + reg); | |
| 121 | 129 | } |
| 122 | 130 | |
| 123 | 131 | static ssize_t gisb_arb_get_timeout(struct device *dev, |
| @@ -296,6 +304,7 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev) · 172 unmodified lines | ||
| 296 | 304 | return -EINVAL; |
| 297 | 305 | } |
| 298 | 306 | gdev->gisb_offsets = of_id->data; |
| 307 | + gdev->big_endian = of_device_is_big_endian(dn); | |
| 299 | 308 | |
| 300 | 309 | err = devm_request_irq(&pdev->dev, timeout_irq, |
| 301 | 310 | brcmstb_gisb_timeout_handler, 0, pdev->name, |
| @@ -50,6 +50,7 @@ obj-$(CONFIG_ARCH_BERLIN) += berlin/ · 49 unmodified lines | ||
| 50 | 50 | obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ |
| 51 | 51 | obj-$(CONFIG_ARCH_HIP04) += hisilicon/ |
| 52 | 52 | obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/ |
| 53 | +obj-$(CONFIG_ARCH_MXC) += imx/ | |
| 53 | 54 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ |
| 54 | 55 | ifeq ($(CONFIG_COMMON_CLK), y) |
| 55 | 56 | obj-$(CONFIG_ARCH_MMP) += mmp/ |
| @@ -72,5 +73,6 @@ obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/ · 16 unmodified lines | ||
| 72 | 73 | obj-$(CONFIG_ARCH_U8500) += ux500/ |
| 73 | 74 | obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ |
| 74 | 75 | obj-$(CONFIG_X86) += x86/ |
| 76 | +obj-$(CONFIG_ARCH_ZX) += zte/ | |
| 75 | 77 | obj-$(CONFIG_ARCH_ZYNQ) += zynq/ |
| 76 | 78 | obj-$(CONFIG_H8300) += h8300/ |
| @@ -0,0 +1,26 @@ | ||
| 1 | + | |
| 2 | +obj-y += \ | |
| 3 | + clk.o \ | |
| 4 | + clk-busy.o \ | |
| 5 | + clk-cpu.o \ | |
| 6 | + clk-fixup-div.o \ | |
| 7 | + clk-fixup-mux.o \ | |
| 8 | + clk-gate-exclusive.o \ | |
| 9 | + clk-gate2.o \ | |
| 10 | + clk-pllv1.o \ | |
| 11 | + clk-pllv2.o \ | |
| 12 | + clk-pllv3.o \ | |
| 13 | + clk-pfd.o | |
| 14 | + | |
| 15 | +obj-$(CONFIG_SOC_IMX1) += clk-imx1.o | |
| 16 | +obj-$(CONFIG_SOC_IMX21) += clk-imx21.o | |
| 17 | +obj-$(CONFIG_SOC_IMX25) += clk-imx25.o | |
| 18 | +obj-$(CONFIG_SOC_IMX27) += clk-imx27.o | |
| 19 | +obj-$(CONFIG_SOC_IMX31) += clk-imx31.o | |
| 20 | +obj-$(CONFIG_SOC_IMX35) += clk-imx35.o | |
| 21 | +obj-$(CONFIG_SOC_IMX5) += clk-imx51-imx53.o | |
| 22 | +obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o | |
| 23 | +obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o | |
| 24 | +obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o | |
| 25 | +obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o | |
| 26 | +obj-$(CONFIG_SOC_VF610) += clk-vf610.o | |
File renamed without changes.
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/clk.h> |
| 13 | 13 | #include <linux/clk-provider.h> |
| 14 | 14 | #include <linux/slab.h> |
| 15 | +#include "clk.h" | |
| 15 | 16 | |
| 16 | 17 | struct clk_cpu { |
| 17 | 18 | struct clk_hw hw; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -23,10 +23,14 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/of.h> |
| 24 | 24 | #include <linux/of_address.h> |
| 25 | 25 | #include <dt-bindings/clock/imx1-clock.h> |
| 26 | +#include <soc/imx/timer.h> | |
| 27 | +#include <asm/irq.h> | |
| 26 | 28 | |
| 27 | 29 | #include "clk.h" |
| 28 | −#include "common.h" | |
| 29 | −#include "hardware.h" | |
| 30 | + | |
| 31 | +#define MX1_CCM_BASE_ADDR 0x0021b000 | |
| 32 | +#define MX1_TIM1_BASE_ADDR 0x00220000 | |
| 33 | +#define MX1_TIM1_INT (NR_IRQS_LEGACY + 59) | |
| 30 | 34 | |
| 31 | 35 | static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", }; |
| 32 | 36 | static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", |
| @@ -50,9 +54,9 @@ static void __init _mx1_clocks_init(unsigned long fref) · 17 unmodified lines | ||
| 50 | 54 | clk[IMX1_CLK_CLK16M] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17); |
| 51 | 55 | clk[IMX1_CLK_CLK32_PREMULT] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1); |
| 52 | 56 | clk[IMX1_CLK_PREM] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks)); |
| 53 | − clk[IMX1_CLK_MPLL] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0); | |
| 57 | + clk[IMX1_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX1, "mpll", "clk32_premult", CCM_MPCTL0); | |
| 54 | 58 | clk[IMX1_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0); |
| 55 | − clk[IMX1_CLK_SPLL] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0); | |
| 59 | + clk[IMX1_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX1, "spll", "prem", CCM_SPCTL0); | |
| 56 | 60 | clk[IMX1_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); |
| 57 | 61 | clk[IMX1_CLK_MCU] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1); |
| 58 | 62 | clk[IMX1_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1); |
| @@ -75,7 +79,8 @@ static void __init _mx1_clocks_init(unsigned long fref) · 16 unmodified lines | ||
| 75 | 79 | |
| 76 | 80 | int __init mx1_clocks_init(unsigned long fref) |
| 77 | 81 | { |
| 78 | − ccm = MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR); | |
| 82 | + ccm = ioremap(MX1_CCM_BASE_ADDR, SZ_4K); | |
| 83 | + BUG_ON(!ccm); | |
| 79 | 84 | |
| 80 | 85 | _mx1_clocks_init(fref); |
| 81 | 86 | |
| @@ -98,7 +103,7 @@ int __init mx1_clocks_init(unsigned long fref) · 16 unmodified lines | ||
| 98 | 103 | clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0"); |
| 99 | 104 | clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0"); |
| 100 | 105 | |
| 101 | − mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); | |
| 106 | + mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT, GPT_TYPE_IMX1); | |
| 102 | 107 | |
| 103 | 108 | return 0; |
| 104 | 109 | } |
| @@ -15,10 +15,14 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/of.h> |
| 16 | 16 | #include <linux/of_address.h> |
| 17 | 17 | #include <dt-bindings/clock/imx21-clock.h> |
| 18 | +#include <soc/imx/timer.h> | |
| 19 | +#include <asm/irq.h> | |
| 18 | 20 | |
| 19 | 21 | #include "clk.h" |
| 20 | −#include "common.h" | |
| 21 | −#include "hardware.h" | |
| 22 | + | |
| 23 | +#define MX21_CCM_BASE_ADDR 0x10027000 | |
| 24 | +#define MX21_GPT1_BASE_ADDR 0x10003000 | |
| 25 | +#define MX21_INT_GPT1 (NR_IRQS_LEGACY + 26) | |
| 22 | 26 | |
| 23 | 27 | static void __iomem *ccm __initdata; |
| 24 | 28 | |
| @@ -63,9 +67,9 @@ static void __init _mx21_clocks_init(unsigned long lref, unsigned long href) · 38 unmodified lines | ||
| 63 | 67 | clk[IMX21_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 26, 3); |
| 64 | 68 | clk[IMX21_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 29, 3); |
| 65 | 69 | |
| 66 | − clk[IMX21_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); | |
| 70 | + clk[IMX21_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "mpll", "mpll_sel", CCM_MPCTL0); | |
| 67 | 71 | |
| 68 | − clk[IMX21_CLK_SPLL] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0); | |
| 72 | + clk[IMX21_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "spll", "spll_sel", CCM_SPCTL0); | |
| 69 | 73 | |
| 70 | 74 | clk[IMX21_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "fclk", CCM_PCDR0, 12, 4); |
| 71 | 75 | clk[IMX21_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6); |
| @@ -153,7 +157,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) · 81 unmodified lines | ||
| 153 | 157 | clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0"); |
| 154 | 158 | clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0"); |
| 155 | 159 | |
| 156 | − mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1); | |
| 160 | + mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, GPT_TYPE_IMX21); | |
| 157 | 161 | |
| 158 | 162 | return 0; |
| 159 | 163 | } |
| @@ -28,8 +28,6 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/of_irq.h> |
| 29 | 29 | |
| 30 | 30 | #include "clk.h" |
| 31 | −#include "common.h" | |
| 32 | −#include "hardware.h" | |
| 33 | 31 | |
| 34 | 32 | #define CCM_MPCTL 0x00 |
| 35 | 33 | #define CCM_UPCTL 0x04 |
| @@ -95,8 +93,8 @@ static int __init __mx25_clocks_init(unsigned long osc_rate, · 59 unmodified lines | ||
| 95 | 93 | |
| 96 | 94 | clk[dummy] = imx_clk_fixed("dummy", 0); |
| 97 | 95 | clk[osc] = imx_clk_fixed("osc", osc_rate); |
| 98 | − clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL)); | |
| 99 | − clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL)); | |
| 96 | + clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "mpll", "osc", ccm(CCM_MPCTL)); | |
| 97 | + clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "upll", "osc", ccm(CCM_UPCTL)); | |
| 100 | 98 | clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4); |
| 101 | 99 | clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); |
| 102 | 100 | clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2); |
| @@ -5,10 +5,15 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <linux/of.h> |
| 6 | 6 | #include <linux/of_address.h> |
| 7 | 7 | #include <dt-bindings/clock/imx27-clock.h> |
| 8 | +#include <soc/imx/revision.h> | |
| 9 | +#include <soc/imx/timer.h> | |
| 10 | +#include <asm/irq.h> | |
| 8 | 11 | |
| 9 | 12 | #include "clk.h" |
| 10 | −#include "common.h" | |
| 11 | −#include "hardware.h" | |
| 13 | + | |
| 14 | +#define MX27_CCM_BASE_ADDR 0x10027000 | |
| 15 | +#define MX27_GPT1_BASE_ADDR 0x10003000 | |
| 16 | +#define MX27_INT_GPT1 (NR_IRQS_LEGACY + 26) | |
| 12 | 17 | |
| 13 | 18 | static void __iomem *ccm __initdata; |
| 14 | 19 | |
| @@ -54,8 +59,8 @@ static void __init _mx27_clocks_init(unsigned long fref) · 39 unmodified lines | ||
| 54 | 59 | clk[IMX27_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3); |
| 55 | 60 | clk[IMX27_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks)); |
| 56 | 61 | clk[IMX27_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks)); |
| 57 | − clk[IMX27_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); | |
| 58 | − clk[IMX27_CLK_SPLL] = imx_clk_pllv1("spll", "ckih_gate", CCM_SPCTL0); | |
| 62 | + clk[IMX27_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX27, "mpll", "mpll_sel", CCM_MPCTL0); | |
| 63 | + clk[IMX27_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX27, "spll", "ckih_gate", CCM_SPCTL0); | |
| 59 | 64 | clk[IMX27_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); |
| 60 | 65 | clk[IMX27_CLK_MPLL_MAIN2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3); |
| 61 | 66 | |
| @@ -229,7 +234,7 @@ int __init mx27_clocks_init(unsigned long fref) · 167 unmodified lines | ||
| 229 | 234 | clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0"); |
| 230 | 235 | clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0"); |
| 231 | 236 | |
| 232 | − mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); | |
| 237 | + mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1, GPT_TYPE_IMX21); | |
| 233 | 238 | |
| 234 | 239 | return 0; |
| 235 | 240 | } |
| @@ -21,12 +21,26 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/io.h> |
| 22 | 22 | #include <linux/err.h> |
| 23 | 23 | #include <linux/of.h> |
| 24 | +#include <soc/imx/revision.h> | |
| 25 | +#include <soc/imx/timer.h> | |
| 26 | +#include <asm/irq.h> | |
| 24 | 27 | |
| 25 | 28 | #include "clk.h" |
| 26 | −#include "common.h" | |
| 27 | −#include "crmregs-imx3.h" | |
| 28 | −#include "hardware.h" | |
| 29 | −#include "mx31.h" | |
| 29 | + | |
| 30 | +#define MX31_CCM_BASE_ADDR 0x53f80000 | |
| 31 | +#define MX31_GPT1_BASE_ADDR 0x53f90000 | |
| 32 | +#define MX31_INT_GPT (NR_IRQS_LEGACY + 29) | |
| 33 | + | |
| 34 | +#define MXC_CCM_CCMR 0x00 | |
| 35 | +#define MXC_CCM_PDR0 0x04 | |
| 36 | +#define MXC_CCM_PDR1 0x08 | |
| 37 | +#define MXC_CCM_MPCTL 0x10 | |
| 38 | +#define MXC_CCM_UPCTL 0x14 | |
| 39 | +#define MXC_CCM_SRPCTL 0x18 | |
| 40 | +#define MXC_CCM_CGR0 0x20 | |
| 41 | +#define MXC_CCM_CGR1 0x24 | |
| 42 | +#define MXC_CCM_CGR2 0x28 | |
| 43 | +#define MXC_CCM_PMCR0 0x5c | |
| 30 | 44 | |
| 31 | 45 | static const char *mcu_main_sel[] = { "spll", "mpll", }; |
| 32 | 46 | static const char *per_sel[] = { "per_div", "ipg", }; |
| @@ -50,15 +64,18 @@ static struct clk_onecell_data clk_data; · 17 unmodified lines | ||
| 50 | 64 | |
| 51 | 65 | int __init mx31_clocks_init(unsigned long fref) |
| 52 | 66 | { |
| 53 | − void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); | |
| 67 | + void __iomem *base; | |
| 54 | 68 | struct device_node *np; |
| 55 | 69 | |
| 70 | + base = ioremap(MX31_CCM_BASE_ADDR, SZ_4K); | |
| 71 | + BUG_ON(!base); | |
| 72 | + | |
| 56 | 73 | clk[dummy] = imx_clk_fixed("dummy", 0); |
| 57 | 74 | clk[ckih] = imx_clk_fixed("ckih", fref); |
| 58 | 75 | clk[ckil] = imx_clk_fixed("ckil", 32768); |
| 59 | − clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL); | |
| 60 | − clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL); | |
| 61 | − clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL); | |
| 76 | + clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "mpll", "ckih", base + MXC_CCM_MPCTL); | |
| 77 | + clk[spll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "spll", "ckih", base + MXC_CCM_SRPCTL); | |
| 78 | + clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "upll", "ckih", base + MXC_CCM_UPCTL); | |
| 62 | 79 | clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel)); |
| 63 | 80 | clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3); |
| 64 | 81 | clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3); |
| @@ -182,7 +199,7 @@ int __init mx31_clocks_init(unsigned long fref) · 117 unmodified lines | ||
| 182 | 199 | mx31_revision(); |
| 183 | 200 | clk_disable_unprepare(clk[iim_gate]); |
| 184 | 201 | |
| 185 | − mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT); | |
| 202 | + mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31); | |
| 186 | 203 | |
| 187 | 204 | return 0; |
| 188 | 205 | } |
| @@ -13,11 +13,26 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/clkdev.h> |
| 14 | 14 | #include <linux/of.h> |
| 15 | 15 | #include <linux/err.h> |
| 16 | +#include <soc/imx/revision.h> | |
| 17 | +#include <soc/imx/timer.h> | |
| 18 | +#include <asm/irq.h> | |
| 16 | 19 | |
| 17 | −#include "crmregs-imx3.h" | |
| 18 | 20 | #include "clk.h" |
| 19 | −#include "common.h" | |
| 20 | −#include "hardware.h" | |
| 21 | + | |
| 22 | +#define MX35_CCM_BASE_ADDR 0x53f80000 | |
| 23 | +#define MX35_GPT1_BASE_ADDR 0x53f90000 | |
| 24 | +#define MX35_INT_GPT (NR_IRQS_LEGACY + 29) | |
| 25 | + | |
| 26 | +#define MXC_CCM_PDR0 0x04 | |
| 27 | +#define MX35_CCM_PDR2 0x0c | |
| 28 | +#define MX35_CCM_PDR3 0x10 | |
| 29 | +#define MX35_CCM_PDR4 0x14 | |
| 30 | +#define MX35_CCM_MPCTL 0x1c | |
| 31 | +#define MX35_CCM_PPCTL 0x20 | |
| 32 | +#define MX35_CCM_CGR0 0x2c | |
| 33 | +#define MX35_CCM_CGR1 0x30 | |
| 34 | +#define MX35_CCM_CGR2 0x34 | |
| 35 | +#define MX35_CCM_CGR3 0x38 | |
| 21 | 36 | |
| 22 | 37 | struct arm_ahb_div { |
| 23 | 38 | unsigned char arm, ahb, sel; |
| @@ -71,11 +86,14 @@ static struct clk *clk[clk_max]; · 47 unmodified lines | ||
| 71 | 86 | |
| 72 | 87 | int __init mx35_clocks_init(void) |
| 73 | 88 | { |
| 74 | − void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); | |
| 89 | + void __iomem *base; | |
| 75 | 90 | u32 pdr0, consumer_sel, hsp_sel; |
| 76 | 91 | struct arm_ahb_div *aad; |
| 77 | 92 | unsigned char *hsp_div; |
| 78 | 93 | |
| 94 | + base = ioremap(MX35_CCM_BASE_ADDR, SZ_4K); | |
| 95 | + BUG_ON(!base); | |
| 96 | + | |
| 79 | 97 | pdr0 = __raw_readl(base + MXC_CCM_PDR0); |
| 80 | 98 | consumer_sel = (pdr0 >> 16) & 0xf; |
| 81 | 99 | aad = &clk_consumer[consumer_sel]; |
| @@ -89,8 +107,8 @@ int __init mx35_clocks_init(void) · 7 unmodified lines | ||
| 89 | 107 | } |
| 90 | 108 | |
| 91 | 109 | clk[ckih] = imx_clk_fixed("ckih", 24000000); |
| 92 | − clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL); | |
| 93 | − clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL); | |
| 110 | + clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL); | |
| 111 | + clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL); | |
| 94 | 112 | |
| 95 | 113 | clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4); |
| 96 | 114 | |
| @@ -276,11 +294,7 @@ int __init mx35_clocks_init(void) · 179 unmodified lines | ||
| 276 | 294 | |
| 277 | 295 | imx_print_silicon_rev("i.MX35", mx35_revision()); |
| 278 | 296 | |
| 279 | −#ifdef CONFIG_MXC_USE_EPIT | |
| 280 | − epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); | |
| 281 | −#else | |
| 282 | − mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); | |
| 283 | −#endif | |
| 297 | + mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31); | |
| 284 | 298 | |
| 285 | 299 | return 0; |
| 286 | 300 | } |
| @@ -16,11 +16,10 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/of.h> |
| 17 | 17 | #include <linux/of_address.h> |
| 18 | 18 | #include <linux/of_irq.h> |
| 19 | +#include <soc/imx/revision.h> | |
| 19 | 20 | #include <dt-bindings/clock/imx5-clock.h> |
| 20 | 21 | |
| 21 | 22 | #include "clk.h" |
| 22 | −#include "common.h" | |
| 23 | −#include "hardware.h" | |
| 24 | 23 | |
| 25 | 24 | #define MX51_DPLL1_BASE 0x83f80000 |
| 26 | 25 | #define MX51_DPLL2_BASE 0x83f84000 |
| @@ -133,8 +132,6 @@ static struct clk_onecell_data clk_data; · 106 unmodified lines | ||
| 133 | 132 | |
| 134 | 133 | static void __init mx5_clocks_common_init(void __iomem *ccm_base) |
| 135 | 134 | { |
| 136 | − imx5_pm_set_ccm_base(ccm_base); | |
| 137 | − | |
| 138 | 135 | clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0); |
| 139 | 136 | clk[IMX5_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); |
| 140 | 137 | clk[IMX5_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); |
| @@ -19,11 +19,10 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/of.h> |
| 20 | 20 | #include <linux/of_address.h> |
| 21 | 21 | #include <linux/of_irq.h> |
| 22 | +#include <soc/imx/revision.h> | |
| 22 | 23 | #include <dt-bindings/clock/imx6qdl-clock.h> |
| 23 | 24 | |
| 24 | 25 | #include "clk.h" |
| 25 | −#include "common.h" | |
| 26 | −#include "hardware.h" | |
| 27 | 26 | |
| 28 | 27 | static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; |
| 29 | 28 | static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; |
| @@ -121,6 +120,16 @@ static unsigned int share_count_ssi2; · 91 unmodified lines | ||
| 121 | 120 | static unsigned int share_count_ssi3; |
| 122 | 121 | static unsigned int share_count_mipi_core_cfg; |
| 123 | 122 | |
| 123 | +static inline int clk_on_imx6q(void) | |
| 124 | +{ | |
| 125 | + return of_machine_is_compatible("fsl,imx6q"); | |
| 126 | +} | |
| 127 | + | |
| 128 | +static inline int clk_on_imx6dl(void) | |
| 129 | +{ | |
| 130 | + return of_machine_is_compatible("fsl,imx6dl"); | |
| 131 | +} | |
| 132 | + | |
| 124 | 133 | static void __init imx6q_clocks_init(struct device_node *ccm_node) |
| 125 | 134 | { |
| 126 | 135 | struct device_node *np; |
| @@ -141,7 +150,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 14 unmodified lines | ||
| 141 | 150 | WARN_ON(!base); |
| 142 | 151 | |
| 143 | 152 | /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ |
| 144 | − if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) { | |
| 153 | + if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) { | |
| 145 | 154 | post_div_table[1].div = 1; |
| 146 | 155 | post_div_table[2].div = 1; |
| 147 | 156 | video_div_table[1].div = 1; |
| @@ -248,7 +257,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 100 unmodified lines | ||
| 248 | 257 | clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); |
| 249 | 258 | clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); |
| 250 | 259 | clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20); |
| 251 | − if (cpu_is_imx6dl()) { | |
| 260 | + if (clk_on_imx6dl()) { | |
| 252 | 261 | clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1); |
| 253 | 262 | clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1); |
| 254 | 263 | } |
| @@ -262,8 +271,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 7 unmodified lines | ||
| 262 | 271 | base = of_iomap(np, 0); |
| 263 | 272 | WARN_ON(!base); |
| 264 | 273 | |
| 265 | − imx6q_pm_set_ccm_base(base); | |
| 266 | − | |
| 267 | 274 | /* name reg shift width parent_names num_parents */ |
| 268 | 275 | clk[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
| 269 | 276 | clk[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); |
| @@ -275,7 +282,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 5 unmodified lines | ||
| 275 | 282 | clk[IMX6QDL_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
| 276 | 283 | clk[IMX6QDL_CLK_ASRC_SEL] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
| 277 | 284 | clk[IMX6QDL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); |
| 278 | − if (cpu_is_imx6q()) { | |
| 285 | + if (clk_on_imx6q()) { | |
| 279 | 286 | clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); |
| 280 | 287 | clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); |
| 281 | 288 | } |
| @@ -382,7 +389,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 100 unmodified lines | ||
| 382 | 389 | clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); |
| 383 | 390 | clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); |
| 384 | 391 | clk[IMX6QDL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); |
| 385 | − if (cpu_is_imx6dl()) | |
| 392 | + if (clk_on_imx6dl()) | |
| 386 | 393 | clk[IMX6DL_CLK_I2C4] = imx_clk_gate2("i2c4", "ipg_per", base + 0x6c, 8); |
| 387 | 394 | else |
| 388 | 395 | clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); |
| @@ -392,7 +399,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 3 unmodified lines | ||
| 392 | 399 | clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); |
| 393 | 400 | clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); |
| 394 | 401 | clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); |
| 395 | − if (cpu_is_imx6dl()) | |
| 402 | + if (clk_on_imx6dl()) | |
| 396 | 403 | /* |
| 397 | 404 | * The multiplexer and divider of imx6q clock gpu3d_shader get |
| 398 | 405 | * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl. |
| @@ -420,7 +427,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 21 unmodified lines | ||
| 420 | 427 | clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg); |
| 421 | 428 | clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg); |
| 422 | 429 | clk[IMX6QDL_CLK_MIPI_IPG] = imx_clk_gate2_shared("mipi_ipg", "ipg", base + 0x74, 16, &share_count_mipi_core_cfg); |
| 423 | − if (cpu_is_imx6dl()) | |
| 430 | + if (clk_on_imx6dl()) | |
| 424 | 431 | /* |
| 425 | 432 | * The multiplexer and divider of the imx6q clock gpu2d get |
| 426 | 433 | * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl. |
| @@ -443,7 +450,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 16 unmodified lines | ||
| 443 | 450 | clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); |
| 444 | 451 | clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); |
| 445 | 452 | clk[IMX6QDL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); |
| 446 | − clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); | |
| 453 | + clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); | |
| 447 | 454 | clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); |
| 448 | 455 | clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); |
| 449 | 456 | clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); |
| @@ -470,7 +477,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 20 unmodified lines | ||
| 470 | 477 | * The gpt_3m clock is not available on i.MX6Q TO1.0. Let's point it |
| 471 | 478 | * to clock gpt_ipg_per to ease the gpt driver code. |
| 472 | 479 | */ |
| 473 | − if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) | |
| 480 | + if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) | |
| 474 | 481 | clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER]; |
| 475 | 482 | |
| 476 | 483 | imx_check_clocks(clk, ARRAY_SIZE(clk)); |
| @@ -482,7 +489,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 5 unmodified lines | ||
| 482 | 489 | clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL); |
| 483 | 490 | |
| 484 | 491 | if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) || |
| 485 | − cpu_is_imx6dl()) { | |
| 492 | + clk_on_imx6dl()) { | |
| 486 | 493 | clk_set_parent(clk[IMX6QDL_CLK_LDB_DI0_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); |
| 487 | 494 | clk_set_parent(clk[IMX6QDL_CLK_LDB_DI1_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); |
| 488 | 495 | } |
| @@ -527,8 +534,5 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) · 38 unmodified lines | ||
| 527 | 534 | /* All existing boards with PCIe use LVDS1 */ |
| 528 | 535 | if (IS_ENABLED(CONFIG_PCI_IMX6)) |
| 529 | 536 | clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); |
| 530 | − | |
| 531 | − /* Set initial power mode */ | |
| 532 | − imx6q_set_lpm(WAIT_CLOCKED); | |
| 533 | 537 | } |
| 534 | 538 | CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <dt-bindings/clock/imx6sl-clock.h> |
| 17 | 17 | |
| 18 | 18 | #include "clk.h" |
| 19 | −#include "common.h" | |
| 20 | 19 | |
| 21 | 20 | #define CCSR 0xc |
| 22 | 21 | #define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2) |
| @@ -288,9 +287,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) · 265 unmodified lines | ||
| 288 | 287 | WARN_ON(!base); |
| 289 | 288 | ccm_base = base; |
| 290 | 289 | |
| 291 | − /* Reuse imx6q pm code */ | |
| 292 | − imx6q_pm_set_ccm_base(base); | |
| 293 | − | |
| 294 | 290 | /* name reg shift width parent_names num_parents */ |
| 295 | 291 | clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
| 296 | 292 | clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); |
| @@ -443,8 +439,5 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) · 146 unmodified lines | ||
| 443 | 439 | |
| 444 | 440 | clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], |
| 445 | 441 | clks[IMX6SL_CLK_PLL2_PFD2]); |
| 446 | − | |
| 447 | − /* Set initial power mode */ | |
| 448 | − imx6q_set_lpm(WAIT_CLOCKED); | |
| 449 | 442 | } |
| 450 | 443 | CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init); |
| @@ -21,7 +21,6 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/types.h> |
| 22 | 22 | |
| 23 | 23 | #include "clk.h" |
| 24 | −#include "common.h" | |
| 25 | 24 | |
| 26 | 25 | #define CCDR 0x4 |
| 27 | 26 | #define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16) |
| @@ -268,8 +267,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) · 240 unmodified lines | ||
| 268 | 267 | base = of_iomap(np, 0); |
| 269 | 268 | WARN_ON(!base); |
| 270 | 269 | |
| 271 | − imx6q_pm_set_ccm_base(base); | |
| 272 | − | |
| 273 | 270 | /* name reg shift width parent_names num_parents */ |
| 274 | 271 | clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); |
| 275 | 272 | clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); |
| @@ -560,8 +557,5 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) · 284 unmodified lines | ||
| 560 | 557 | |
| 561 | 558 | clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); |
| 562 | 559 | clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); |
| 563 | − | |
| 564 | − /* Set initial power mode */ | |
| 565 | − imx6q_set_lpm(WAIT_CLOCKED); | |
| 566 | 560 | } |
| 567 | 561 | CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init); |
| @@ -0,0 +1,860 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. | |
| 3 | + * | |
| 4 | + * The code contained herein is licensed under the GNU General Public | |
| 5 | + * License. You may obtain a copy of the GNU General Public License | |
| 6 | + * Version 2 or later at the following locations: | |
| 7 | + * | |
| 8 | + * http://www.opensource.org/licenses/gpl-license.html | |
| 9 | + * http://www.gnu.org/copyleft/gpl.html | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <dt-bindings/clock/imx7d-clock.h> | |
| 13 | +#include <linux/clk.h> | |
| 14 | +#include <linux/clkdev.h> | |
| 15 | +#include <linux/err.h> | |
| 16 | +#include <linux/init.h> | |
| 17 | +#include <linux/io.h> | |
| 18 | +#include <linux/of.h> | |
| 19 | +#include <linux/of_address.h> | |
| 20 | +#include <linux/of_irq.h> | |
| 21 | +#include <linux/types.h> | |
| 22 | + | |
| 23 | +#include "clk.h" | |
| 24 | + | |
| 25 | +static struct clk *clks[IMX7D_CLK_END]; | |
| 26 | +static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk", | |
| 27 | + "pll_enet_500m_clk", "pll_dram_main_clk", | |
| 28 | + "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_main_clk", | |
| 29 | + "pll_usb_main_clk", }; | |
| 30 | + | |
| 31 | +static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 32 | + "pll_enet_250m_clk", "pll_sys_pfd2_270m_clk", | |
| 33 | + "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", | |
| 34 | + "pll_usb_main_clk", }; | |
| 35 | + | |
| 36 | +static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk", | |
| 37 | + "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk", | |
| 38 | + "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", | |
| 39 | + "pll_usb_main_clk", }; | |
| 40 | + | |
| 41 | +static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk", | |
| 42 | + "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk", | |
| 43 | + "pll_audio_main_clk", "pll_video_main_clk", "pll_sys_pfd7_clk", }; | |
| 44 | + | |
| 45 | +static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk", | |
| 46 | + "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk", | |
| 47 | + "pll_sys_pfd7_clk", "pll_audio_main_clk", "pll_video_main_clk", }; | |
| 48 | + | |
| 49 | +static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk", | |
| 50 | + "pll_dram_533m_clk", "pll_enet_250m_clk", | |
| 51 | + "pll_sys_main_240m_clk", "pll_audio_main_clk", "pll_video_main_clk", | |
| 52 | + "pll_sys_pfd4_clk", }; | |
| 53 | + | |
| 54 | +static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk", | |
| 55 | + "pll_dram_533m_clk", "pll_sys_main_240m_clk", | |
| 56 | + "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk", | |
| 57 | + "pll_audio_main_clk", }; | |
| 58 | + | |
| 59 | +static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 60 | + "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", | |
| 61 | + "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk", | |
| 62 | + "pll_video_main_clk", }; | |
| 63 | + | |
| 64 | +static const char *dram_phym_sel[] = { "pll_dram_main_clk", | |
| 65 | + "dram_phym_alt_clk", }; | |
| 66 | + | |
| 67 | +static const char *dram_sel[] = { "pll_dram_main_clk", | |
| 68 | + "dram_alt_clk", }; | |
| 69 | + | |
| 70 | +static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk", | |
| 71 | + "pll_sys_main_clk", "pll_enet_500m_clk", | |
| 72 | + "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_main_clk", | |
| 73 | + "pll_video_main_clk", }; | |
| 74 | + | |
| 75 | +static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk", | |
| 76 | + "pll_sys_main_clk", "pll_enet_500m_clk", | |
| 77 | + "pll_enet_250m_clk", "pll_sys_pfd0_392m_clk", | |
| 78 | + "pll_audio_main_clk", "pll_sys_pfd2_270m_clk", }; | |
| 79 | + | |
| 80 | +static const char *usb_hsic_sel[] = { "osc", "pll_sys_main_clk", | |
| 81 | + "pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk", | |
| 82 | + "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; | |
| 83 | + | |
| 84 | +static const char *pcie_ctrl_sel[] = { "osc", "pll_enet_250m_clk", | |
| 85 | + "pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk", | |
| 86 | + "pll_dram_533m_clk", "pll_enet_500m_clk", | |
| 87 | + "pll_sys_pfd1_332m_clk", "pll_sys_pfd6_clk", }; | |
| 88 | + | |
| 89 | +static const char *pcie_phy_sel[] = { "osc", "pll_enet_100m_clk", | |
| 90 | + "pll_enet_500m_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", | |
| 91 | + "ext_clk_4", "pll_sys_pfd0_392m_clk", }; | |
| 92 | + | |
| 93 | +static const char *epdc_pixel_sel[] = { "osc", "pll_sys_pfd1_332m_clk", | |
| 94 | + "pll_dram_533m_clk", "pll_sys_main_clk", "pll_sys_pfd5_clk", | |
| 95 | + "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", "pll_video_main_clk", }; | |
| 96 | + | |
| 97 | +static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk", | |
| 98 | + "pll_dram_533m_clk", "ext_clk_3", "pll_sys_pfd4_clk", | |
| 99 | + "pll_sys_pfd2_270m_clk", "pll_video_main_clk", | |
| 100 | + "pll_usb_main_clk", }; | |
| 101 | + | |
| 102 | +static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk", | |
| 103 | + "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk", | |
| 104 | + "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", }; | |
| 105 | + | |
| 106 | +static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk", | |
| 107 | + "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk", | |
| 108 | + "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", }; | |
| 109 | + | |
| 110 | +static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk", | |
| 111 | + "pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2", | |
| 112 | + "pll_video_main_clk", "ext_clk_3", }; | |
| 113 | + | |
| 114 | +static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 115 | + "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", | |
| 116 | + "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", }; | |
| 117 | + | |
| 118 | +static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 119 | + "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", | |
| 120 | + "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", }; | |
| 121 | + | |
| 122 | +static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 123 | + "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", | |
| 124 | + "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", }; | |
| 125 | + | |
| 126 | +static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 127 | + "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", | |
| 128 | + "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", }; | |
| 129 | + | |
| 130 | +static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk", | |
| 131 | + "pll_enet_50m_clk", "pll_enet_25m_clk", | |
| 132 | + "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk", | |
| 133 | + "ext_clk_4", }; | |
| 134 | + | |
| 135 | +static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk", | |
| 136 | + "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", | |
| 137 | + "ext_clk_4", "pll_video_main_clk", }; | |
| 138 | + | |
| 139 | +static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk", | |
| 140 | + "pll_enet_50m_clk", "pll_enet_25m_clk", | |
| 141 | + "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk", | |
| 142 | + "ext_clk_4", }; | |
| 143 | + | |
| 144 | +static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk", | |
| 145 | + "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", | |
| 146 | + "ext_clk_4", "pll_video_main_clk", }; | |
| 147 | + | |
| 148 | +static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk", | |
| 149 | + "pll_enet_50m_clk", "pll_enet_125m_clk", | |
| 150 | + "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", | |
| 151 | + "pll_sys_pfd3_clk", }; | |
| 152 | + | |
| 153 | +static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 154 | + "pll_sys_main_120m_clk", "pll_dram_533m_clk", | |
| 155 | + "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_enet_125m_clk", | |
| 156 | + "pll_usb_main_clk", }; | |
| 157 | + | |
| 158 | +static const char *nand_sel[] = { "osc", "pll_sys_main_clk", | |
| 159 | + "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd3_clk", | |
| 160 | + "pll_enet_500m_clk", "pll_enet_250m_clk", | |
| 161 | + "pll_video_main_clk", }; | |
| 162 | + | |
| 163 | +static const char *qspi_sel[] = { "osc", "pll_sys_pfd4_clk", | |
| 164 | + "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd3_clk", | |
| 165 | + "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; | |
| 166 | + | |
| 167 | +static const char *usdhc1_sel[] = { "osc", "pll_sys_pfd0_392m_clk", | |
| 168 | + "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk", | |
| 169 | + "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; | |
| 170 | + | |
| 171 | +static const char *usdhc2_sel[] = { "osc", "pll_sys_pfd0_392m_clk", | |
| 172 | + "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk", | |
| 173 | + "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; | |
| 174 | + | |
| 175 | +static const char *usdhc3_sel[] = { "osc", "pll_sys_pfd0_392m_clk", | |
| 176 | + "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk", | |
| 177 | + "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", }; | |
| 178 | + | |
| 179 | +static const char *can1_sel[] = { "osc", "pll_sys_main_120m_clk", | |
| 180 | + "pll_dram_533m_clk", "pll_sys_main_clk", | |
| 181 | + "pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1", | |
| 182 | + "ext_clk_4", }; | |
| 183 | + | |
| 184 | +static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk", | |
| 185 | + "pll_dram_533m_clk", "pll_sys_main_clk", | |
| 186 | + "pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1", | |
| 187 | + "ext_clk_3", }; | |
| 188 | + | |
| 189 | +static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk", | |
| 190 | + "pll_enet_50m_clk", "pll_dram_533m_clk", | |
| 191 | + "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", | |
| 192 | + "pll_sys_pfd2_135m_clk", }; | |
| 193 | + | |
| 194 | +static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk", | |
| 195 | + "pll_enet_50m_clk", "pll_dram_533m_clk", | |
| 196 | + "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", | |
| 197 | + "pll_sys_pfd2_135m_clk", }; | |
| 198 | + | |
| 199 | +static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk", | |
| 200 | + "pll_enet_50m_clk", "pll_dram_533m_clk", | |
| 201 | + "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", | |
| 202 | + "pll_sys_pfd2_135m_clk", }; | |
| 203 | + | |
| 204 | +static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk", | |
| 205 | + "pll_enet_50m_clk", "pll_dram_533m_clk", | |
| 206 | + "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", | |
| 207 | + "pll_sys_pfd2_135m_clk", }; | |
| 208 | + | |
| 209 | +static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 210 | + "pll_enet_40m_clk", "pll_enet_100m_clk", | |
| 211 | + "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", | |
| 212 | + "pll_usb_main_clk", }; | |
| 213 | + | |
| 214 | +static const char *uart2_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 215 | + "pll_enet_40m_clk", "pll_enet_100m_clk", | |
| 216 | + "pll_sys_main_clk", "ext_clk_2", "ext_clk_3", | |
| 217 | + "pll_usb_main_clk", }; | |
| 218 | + | |
| 219 | +static const char *uart3_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 220 | + "pll_enet_40m_clk", "pll_enet_100m_clk", | |
| 221 | + "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", | |
| 222 | + "pll_usb_main_clk", }; | |
| 223 | + | |
| 224 | +static const char *uart4_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 225 | + "pll_enet_40m_clk", "pll_enet_100m_clk", | |
| 226 | + "pll_sys_main_clk", "ext_clk_2", "ext_clk_3", | |
| 227 | + "pll_usb_main_clk", }; | |
| 228 | + | |
| 229 | +static const char *uart5_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 230 | + "pll_enet_40m_clk", "pll_enet_100m_clk", | |
| 231 | + "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", | |
| 232 | + "pll_usb_main_clk", }; | |
| 233 | + | |
| 234 | +static const char *uart6_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 235 | + "pll_enet_40m_clk", "pll_enet_100m_clk", | |
| 236 | + "pll_sys_main_clk", "ext_clk_2", "ext_clk_3", | |
| 237 | + "pll_usb_main_clk", }; | |
| 238 | + | |
| 239 | +static const char *uart7_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 240 | + "pll_enet_40m_clk", "pll_enet_100m_clk", | |
| 241 | + "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", | |
| 242 | + "pll_usb_main_clk", }; | |
| 243 | + | |
| 244 | +static const char *ecspi1_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 245 | + "pll_enet_40m_clk", "pll_sys_main_120m_clk", | |
| 246 | + "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk", | |
| 247 | + "pll_usb_main_clk", }; | |
| 248 | + | |
| 249 | +static const char *ecspi2_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 250 | + "pll_enet_40m_clk", "pll_sys_main_120m_clk", | |
| 251 | + "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk", | |
| 252 | + "pll_usb_main_clk", }; | |
| 253 | + | |
| 254 | +static const char *ecspi3_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 255 | + "pll_enet_40m_clk", "pll_sys_main_120m_clk", | |
| 256 | + "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk", | |
| 257 | + "pll_usb_main_clk", }; | |
| 258 | + | |
| 259 | +static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 260 | + "pll_enet_40m_clk", "pll_sys_main_120m_clk", | |
| 261 | + "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk", | |
| 262 | + "pll_usb_main_clk", }; | |
| 263 | + | |
| 264 | +static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk", | |
| 265 | + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", | |
| 266 | + "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", }; | |
| 267 | + | |
| 268 | +static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk", | |
| 269 | + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", | |
| 270 | + "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", }; | |
| 271 | + | |
| 272 | +static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk", | |
| 273 | + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", | |
| 274 | + "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", }; | |
| 275 | + | |
| 276 | +static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk", | |
| 277 | + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", | |
| 278 | + "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", }; | |
| 279 | + | |
| 280 | +static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk", | |
| 281 | + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", | |
| 282 | + "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", }; | |
| 283 | + | |
| 284 | +static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk", | |
| 285 | + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", | |
| 286 | + "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", }; | |
| 287 | + | |
| 288 | +static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 289 | + "pll_sys_main_120m_clk", "pll_dram_533m_clk", | |
| 290 | + "pll_usb_main_clk", "pll_audio_main_clk", "pll_enet_125m_clk", | |
| 291 | + "pll_sys_pfd7_clk", }; | |
| 292 | + | |
| 293 | +static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 294 | + "pll_sys_main_120m_clk", "pll_dram_533m_clk", | |
| 295 | + "pll_usb_main_clk", "pll_video_main_clk", "pll_enet_125m_clk", | |
| 296 | + "pll_sys_pfd7_clk", }; | |
| 297 | + | |
| 298 | +static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk", | |
| 299 | + "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", | |
| 300 | + "ref_1m_clk", "pll_audio_main_clk", "ext_clk_1", }; | |
| 301 | + | |
| 302 | +static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk", | |
| 303 | + "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", | |
| 304 | + "ref_1m_clk", "pll_audio_main_clk", "ext_clk_2", }; | |
| 305 | + | |
| 306 | +static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk", | |
| 307 | + "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", | |
| 308 | + "ref_1m_clk", "pll_audio_main_clk", "ext_clk_3", }; | |
| 309 | + | |
| 310 | +static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk", | |
| 311 | + "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", | |
| 312 | + "ref_1m_clk", "pll_audio_main_clk", "ext_clk_4", }; | |
| 313 | + | |
| 314 | +static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 315 | + "pll_sys_main_120m_clk", "pll_dram_533m_clk", | |
| 316 | + "pll_enet_125m_clk", "pll_usb_main_clk", "ext_clk_2", | |
| 317 | + "ext_clk_3", }; | |
| 318 | + | |
| 319 | +static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 320 | + "pll_sys_main_120m_clk", "pll_dram_533m_clk", | |
| 321 | + "pll_enet_125m_clk", "pll_usb_main_clk", "ref_1m_clk", | |
| 322 | + "pll_sys_pfd1_166m_clk", }; | |
| 323 | + | |
| 324 | +static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 325 | + "pll_sys_main_120m_clk", "pll_dram_533m_clk", | |
| 326 | + "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk", | |
| 327 | + "pll_usb_main_clk", }; | |
| 328 | + | |
| 329 | +static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk", | |
| 330 | + "pll_sys_main_120m_clk", "pll_dram_533m_clk", | |
| 331 | + "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk", | |
| 332 | + "pll_usb_main_clk", }; | |
| 333 | + | |
| 334 | +static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk", | |
| 335 | + "pll_dram_533m_clk", "pll_usb_main_clk", | |
| 336 | + "pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk", | |
| 337 | + "pll_enet_500m_clk", "pll_sys_pfd7_clk", }; | |
| 338 | + | |
| 339 | +static const char *clko1_sel[] = { "osc", "pll_sys_main_clk", | |
| 340 | + "pll_sys_main_240m_clk", "pll_sys_pfd0_196m_clk", "pll_sys_pfd3_clk", | |
| 341 | + "pll_enet_500m_clk", "pll_dram_533m_clk", "ref_1m_clk", }; | |
| 342 | + | |
| 343 | +static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk", | |
| 344 | + "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk", | |
| 345 | + "pll_audio_main_clk", "pll_video_main_clk", "osc_32k_clk", }; | |
| 346 | + | |
| 347 | +static const char *lvds1_sel[] = { "pll_arm_main_clk", | |
| 348 | + "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk", | |
| 349 | + "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk", | |
| 350 | + "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", | |
| 351 | + "pll_audio_main_clk", "pll_video_main_clk", "pll_enet_500m_clk", | |
| 352 | + "pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk", | |
| 353 | + "pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk", | |
| 354 | + "pll_dram_main_clk", }; | |
| 355 | + | |
| 356 | +static const char *pll_bypass_src_sel[] = { "osc", "dummy", }; | |
| 357 | +static const char *pll_arm_bypass_sel[] = { "pll_arm_main", "pll_arm_main_src", }; | |
| 358 | +static const char *pll_dram_bypass_sel[] = { "pll_dram_main", "pll_dram_main_src", }; | |
| 359 | +static const char *pll_sys_bypass_sel[] = { "pll_sys_main", "pll_sys_main_src", }; | |
| 360 | +static const char *pll_enet_bypass_sel[] = { "pll_enet_main", "pll_enet_main_src", }; | |
| 361 | +static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", }; | |
| 362 | +static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", }; | |
| 363 | + | |
| 364 | +static struct clk_onecell_data clk_data; | |
| 365 | + | |
| 366 | +static void __init imx7d_clocks_init(struct device_node *ccm_node) | |
| 367 | +{ | |
| 368 | + struct device_node *np; | |
| 369 | + void __iomem *base; | |
| 370 | + int i; | |
| 371 | + | |
| 372 | + clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | |
| 373 | + clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc"); | |
| 374 | + | |
| 375 | + np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); | |
| 376 | + base = of_iomap(np, 0); | |
| 377 | + WARN_ON(!base); | |
| 378 | + | |
| 379 | + clks[IMX7D_PLL_ARM_MAIN_SRC] = imx_clk_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | |
| 380 | + clks[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | |
| 381 | + clks[IMX7D_PLL_SYS_MAIN_SRC] = imx_clk_mux("pll_sys_main_src", base + 0xb0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | |
| 382 | + clks[IMX7D_PLL_ENET_MAIN_SRC] = imx_clk_mux("pll_enet_main_src", base + 0xe0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | |
| 383 | + clks[IMX7D_PLL_AUDIO_MAIN_SRC] = imx_clk_mux("pll_audio_main_src", base + 0xf0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | |
| 384 | + clks[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); | |
| 385 | + | |
| 386 | + clks[IMX7D_PLL_ARM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "pll_arm_main_src", base + 0x60, 0x7f); | |
| 387 | + clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_dram_main", "pll_dram_main_src", base + 0x70, 0x7f); | |
| 388 | + clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "pll_sys_main_src", base + 0xb0, 0x1); | |
| 389 | + clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "pll_enet_main_src", base + 0xe0, 0x0); | |
| 390 | + clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "pll_audio_main_src", base + 0xf0, 0x7f); | |
| 391 | + clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "pll_video_main_src", base + 0x130, 0x7f); | |
| 392 | + | |
| 393 | + clks[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT); | |
| 394 | + clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT); | |
| 395 | + clks[IMX7D_PLL_SYS_MAIN_BYPASS] = imx_clk_mux_flags("pll_sys_main_bypass", base + 0xb0, 16, 1, pll_sys_bypass_sel, ARRAY_SIZE(pll_sys_bypass_sel), CLK_SET_RATE_PARENT); | |
| 396 | + clks[IMX7D_PLL_ENET_MAIN_BYPASS] = imx_clk_mux_flags("pll_enet_main_bypass", base + 0xe0, 16, 1, pll_enet_bypass_sel, ARRAY_SIZE(pll_enet_bypass_sel), CLK_SET_RATE_PARENT); | |
| 397 | + clks[IMX7D_PLL_AUDIO_MAIN_BYPASS] = imx_clk_mux_flags("pll_audio_main_bypass", base + 0xf0, 16, 1, pll_audio_bypass_sel, ARRAY_SIZE(pll_audio_bypass_sel), CLK_SET_RATE_PARENT); | |
| 398 | + clks[IMX7D_PLL_VIDEO_MAIN_BYPASS] = imx_clk_mux_flags("pll_video_main_bypass", base + 0x130, 16, 1, pll_video_bypass_sel, ARRAY_SIZE(pll_video_bypass_sel), CLK_SET_RATE_PARENT); | |
| 399 | + | |
| 400 | + clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]); | |
| 401 | + clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]); | |
| 402 | + clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]); | |
| 403 | + clk_set_parent(clks[IMX7D_PLL_ENET_MAIN_BYPASS], clks[IMX7D_PLL_ENET_MAIN]); | |
| 404 | + clk_set_parent(clks[IMX7D_PLL_AUDIO_MAIN_BYPASS], clks[IMX7D_PLL_AUDIO_MAIN]); | |
| 405 | + clk_set_parent(clks[IMX7D_PLL_VIDEO_MAIN_BYPASS], clks[IMX7D_PLL_VIDEO_MAIN]); | |
| 406 | + | |
| 407 | + clks[IMX7D_PLL_ARM_MAIN_CLK] = imx_clk_gate("pll_arm_main_clk", "pll_arm_main_bypass", base + 0x60, 13); | |
| 408 | + clks[IMX7D_PLL_DRAM_MAIN_CLK] = imx_clk_gate("pll_dram_main_clk", "pll_dram_main_bypass", base + 0x70, 13); | |
| 409 | + clks[IMX7D_PLL_SYS_MAIN_CLK] = imx_clk_gate("pll_sys_main_clk", "pll_sys_main_bypass", base + 0xb0, 13); | |
| 410 | + clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13); | |
| 411 | + clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13); | |
| 412 | + | |
| 413 | + clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0); | |
| 414 | + clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1); | |
| 415 | + clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2); | |
| 416 | + | |
| 417 | + clks[IMX7D_PLL_SYS_PFD3_CLK] = imx_clk_pfd("pll_sys_pfd3_clk", "pll_sys_main_clk", base + 0xc0, 3); | |
| 418 | + clks[IMX7D_PLL_SYS_PFD4_CLK] = imx_clk_pfd("pll_sys_pfd4_clk", "pll_sys_main_clk", base + 0xd0, 0); | |
| 419 | + clks[IMX7D_PLL_SYS_PFD5_CLK] = imx_clk_pfd("pll_sys_pfd5_clk", "pll_sys_main_clk", base + 0xd0, 1); | |
| 420 | + clks[IMX7D_PLL_SYS_PFD6_CLK] = imx_clk_pfd("pll_sys_pfd6_clk", "pll_sys_main_clk", base + 0xd0, 2); | |
| 421 | + clks[IMX7D_PLL_SYS_PFD7_CLK] = imx_clk_pfd("pll_sys_pfd7_clk", "pll_sys_main_clk", base + 0xd0, 3); | |
| 422 | + | |
| 423 | + clks[IMX7D_PLL_SYS_MAIN_480M] = imx_clk_fixed_factor("pll_sys_main_480m", "pll_sys_main_clk", 1, 1); | |
| 424 | + clks[IMX7D_PLL_SYS_MAIN_240M] = imx_clk_fixed_factor("pll_sys_main_240m", "pll_sys_main_clk", 1, 2); | |
| 425 | + clks[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_fixed_factor("pll_sys_main_120m", "pll_sys_main_clk", 1, 4); | |
| 426 | + clks[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2); | |
| 427 | + | |
| 428 | + clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4); | |
| 429 | + clks[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5); | |
| 430 | + clks[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6); | |
| 431 | + clks[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12); | |
| 432 | + | |
| 433 | + clks[IMX7D_PLL_SYS_PFD0_196M] = imx_clk_fixed_factor("pll_sys_pfd0_196m", "pll_sys_pfd0_392m_clk", 1, 2); | |
| 434 | + clks[IMX7D_PLL_SYS_PFD1_166M] = imx_clk_fixed_factor("pll_sys_pfd1_166m", "pll_sys_pfd1_332m_clk", 1, 2); | |
| 435 | + clks[IMX7D_PLL_SYS_PFD2_135M] = imx_clk_fixed_factor("pll_sys_pfd2_135m", "pll_sys_pfd2_270m_clk", 1, 2); | |
| 436 | + | |
| 437 | + clks[IMX7D_PLL_SYS_PFD0_196M_CLK] = imx_clk_gate_dis("pll_sys_pfd0_196m_clk", "pll_sys_pfd0_196m", base + 0xb0, 26); | |
| 438 | + clks[IMX7D_PLL_SYS_PFD1_166M_CLK] = imx_clk_gate_dis("pll_sys_pfd1_166m_clk", "pll_sys_pfd1_166m", base + 0xb0, 27); | |
| 439 | + clks[IMX7D_PLL_SYS_PFD2_135M_CLK] = imx_clk_gate_dis("pll_sys_pfd2_135m_clk", "pll_sys_pfd2_135m", base + 0xb0, 28); | |
| 440 | + | |
| 441 | + clks[IMX7D_PLL_ENET_MAIN_CLK] = imx_clk_fixed_factor("pll_enet_main_clk", "pll_enet_main_bypass", 1, 1); | |
| 442 | + clks[IMX7D_PLL_ENET_MAIN_500M] = imx_clk_fixed_factor("pll_enet_500m", "pll_enet_main_clk", 1, 2); | |
| 443 | + clks[IMX7D_PLL_ENET_MAIN_250M] = imx_clk_fixed_factor("pll_enet_250m", "pll_enet_main_clk", 1, 4); | |
| 444 | + clks[IMX7D_PLL_ENET_MAIN_125M] = imx_clk_fixed_factor("pll_enet_125m", "pll_enet_main_clk", 1, 8); | |
| 445 | + clks[IMX7D_PLL_ENET_MAIN_100M] = imx_clk_fixed_factor("pll_enet_100m", "pll_enet_main_clk", 1, 10); | |
| 446 | + clks[IMX7D_PLL_ENET_MAIN_50M] = imx_clk_fixed_factor("pll_enet_50m", "pll_enet_main_clk", 1, 20); | |
| 447 | + clks[IMX7D_PLL_ENET_MAIN_40M] = imx_clk_fixed_factor("pll_enet_40m", "pll_enet_main_clk", 1, 25); | |
| 448 | + clks[IMX7D_PLL_ENET_MAIN_25M] = imx_clk_fixed_factor("pll_enet_25m", "pll_enet_main_clk", 1, 40); | |
| 449 | + | |
| 450 | + clks[IMX7D_PLL_ENET_MAIN_500M_CLK] = imx_clk_gate("pll_enet_500m_clk", "pll_enet_500m", base + 0xe0, 12); | |
| 451 | + clks[IMX7D_PLL_ENET_MAIN_250M_CLK] = imx_clk_gate("pll_enet_250m_clk", "pll_enet_250m", base + 0xe0, 11); | |
| 452 | + clks[IMX7D_PLL_ENET_MAIN_125M_CLK] = imx_clk_gate("pll_enet_125m_clk", "pll_enet_125m", base + 0xe0, 10); | |
| 453 | + clks[IMX7D_PLL_ENET_MAIN_100M_CLK] = imx_clk_gate("pll_enet_100m_clk", "pll_enet_100m", base + 0xe0, 9); | |
| 454 | + clks[IMX7D_PLL_ENET_MAIN_50M_CLK] = imx_clk_gate("pll_enet_50m_clk", "pll_enet_50m", base + 0xe0, 8); | |
| 455 | + clks[IMX7D_PLL_ENET_MAIN_40M_CLK] = imx_clk_gate("pll_enet_40m_clk", "pll_enet_40m", base + 0xe0, 7); | |
| 456 | + clks[IMX7D_PLL_ENET_MAIN_25M_CLK] = imx_clk_gate("pll_enet_25m_clk", "pll_enet_25m", base + 0xe0, 6); | |
| 457 | + | |
| 458 | + clks[IMX7D_LVDS1_OUT_SEL] = imx_clk_mux("lvds1_sel", base + 0x170, 0, 5, lvds1_sel, ARRAY_SIZE(lvds1_sel)); | |
| 459 | + clks[IMX7D_LVDS1_OUT_CLK] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x170, 5, BIT(6)); | |
| 460 | + | |
| 461 | + np = ccm_node; | |
| 462 | + base = of_iomap(np, 0); | |
| 463 | + WARN_ON(!base); | |
| 464 | + | |
| 465 | + clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel)); | |
| 466 | + clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel)); | |
| 467 | + clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel)); | |
| 468 | + clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel)); | |
| 469 | + clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel)); | |
| 470 | + clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel)); | |
| 471 | + clks[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_mux("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel)); | |
| 472 | + clks[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_mux("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel)); | |
| 473 | + clks[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_mux("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel)); | |
| 474 | + clks[IMX7D_DRAM_ROOT_SRC] = imx_clk_mux("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel)); | |
| 475 | + clks[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_mux("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel)); | |
| 476 | + clks[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_mux("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel)); | |
| 477 | + clks[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_mux("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel)); | |
| 478 | + clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel)); | |
| 479 | + clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel)); | |
| 480 | + clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel)); | |
| 481 | + clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel)); | |
| 482 | + clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel)); | |
| 483 | + clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel)); | |
| 484 | + clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel)); | |
| 485 | + clks[IMX7D_SAI1_ROOT_SRC] = imx_clk_mux("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel)); | |
| 486 | + clks[IMX7D_SAI2_ROOT_SRC] = imx_clk_mux("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel)); | |
| 487 | + clks[IMX7D_SAI3_ROOT_SRC] = imx_clk_mux("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel)); | |
| 488 | + clks[IMX7D_SPDIF_ROOT_SRC] = imx_clk_mux("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel)); | |
| 489 | + clks[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_mux("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel)); | |
| 490 | + clks[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_mux("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel)); | |
| 491 | + clks[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_mux("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel)); | |
| 492 | + clks[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_mux("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel)); | |
| 493 | + clks[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_mux("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel)); | |
| 494 | + clks[IMX7D_EIM_ROOT_SRC] = imx_clk_mux("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel)); | |
| 495 | + clks[IMX7D_NAND_ROOT_SRC] = imx_clk_mux("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel)); | |
| 496 | + clks[IMX7D_QSPI_ROOT_SRC] = imx_clk_mux("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel)); | |
| 497 | + clks[IMX7D_USDHC1_ROOT_SRC] = imx_clk_mux("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel)); | |
| 498 | + clks[IMX7D_USDHC2_ROOT_SRC] = imx_clk_mux("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel)); | |
| 499 | + clks[IMX7D_USDHC3_ROOT_SRC] = imx_clk_mux("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel)); | |
| 500 | + clks[IMX7D_CAN1_ROOT_SRC] = imx_clk_mux("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel)); | |
| 501 | + clks[IMX7D_CAN2_ROOT_SRC] = imx_clk_mux("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel)); | |
| 502 | + clks[IMX7D_I2C1_ROOT_SRC] = imx_clk_mux("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel)); | |
| 503 | + clks[IMX7D_I2C2_ROOT_SRC] = imx_clk_mux("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel)); | |
| 504 | + clks[IMX7D_I2C3_ROOT_SRC] = imx_clk_mux("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel)); | |
| 505 | + clks[IMX7D_I2C4_ROOT_SRC] = imx_clk_mux("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel)); | |
| 506 | + clks[IMX7D_UART1_ROOT_SRC] = imx_clk_mux("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel)); | |
| 507 | + clks[IMX7D_UART2_ROOT_SRC] = imx_clk_mux("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel)); | |
| 508 | + clks[IMX7D_UART3_ROOT_SRC] = imx_clk_mux("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel)); | |
| 509 | + clks[IMX7D_UART4_ROOT_SRC] = imx_clk_mux("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel)); | |
| 510 | + clks[IMX7D_UART5_ROOT_SRC] = imx_clk_mux("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel)); | |
| 511 | + clks[IMX7D_UART6_ROOT_SRC] = imx_clk_mux("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel)); | |
| 512 | + clks[IMX7D_UART7_ROOT_SRC] = imx_clk_mux("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel)); | |
| 513 | + clks[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_mux("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel)); | |
| 514 | + clks[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_mux("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel)); | |
| 515 | + clks[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_mux("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel)); | |
| 516 | + clks[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_mux("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel)); | |
| 517 | + clks[IMX7D_PWM1_ROOT_SRC] = imx_clk_mux("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel)); | |
| 518 | + clks[IMX7D_PWM2_ROOT_SRC] = imx_clk_mux("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel)); | |
| 519 | + clks[IMX7D_PWM3_ROOT_SRC] = imx_clk_mux("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel)); | |
| 520 | + clks[IMX7D_PWM4_ROOT_SRC] = imx_clk_mux("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel)); | |
| 521 | + clks[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_mux("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel)); | |
| 522 | + clks[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_mux("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel)); | |
| 523 | + clks[IMX7D_SIM1_ROOT_SRC] = imx_clk_mux("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel)); | |
| 524 | + clks[IMX7D_SIM2_ROOT_SRC] = imx_clk_mux("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel)); | |
| 525 | + clks[IMX7D_GPT1_ROOT_SRC] = imx_clk_mux("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel)); | |
| 526 | + clks[IMX7D_GPT2_ROOT_SRC] = imx_clk_mux("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel)); | |
| 527 | + clks[IMX7D_GPT3_ROOT_SRC] = imx_clk_mux("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel)); | |
| 528 | + clks[IMX7D_GPT4_ROOT_SRC] = imx_clk_mux("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel)); | |
| 529 | + clks[IMX7D_TRACE_ROOT_SRC] = imx_clk_mux("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel)); | |
| 530 | + clks[IMX7D_WDOG_ROOT_SRC] = imx_clk_mux("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel)); | |
| 531 | + clks[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_mux("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel)); | |
| 532 | + clks[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_mux("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel)); | |
| 533 | + clks[IMX7D_WRCLK_ROOT_SRC] = imx_clk_mux("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel)); | |
| 534 | + clks[IMX7D_CLKO1_ROOT_SRC] = imx_clk_mux("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel)); | |
| 535 | + clks[IMX7D_CLKO2_ROOT_SRC] = imx_clk_mux("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel)); | |
| 536 | + | |
| 537 | + clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate("arm_a7_cg", "arm_a7_src", base + 0x8000, 28); | |
| 538 | + clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); | |
| 539 | + clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate("arm_m0_cg", "arm_m0_src", base + 0x8100, 28); | |
| 540 | + clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate("axi_cg", "axi_src", base + 0x8800, 28); | |
| 541 | + clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate("disp_axi_cg", "disp_axi_src", base + 0x8880, 28); | |
| 542 | + clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate("enet_axi_cg", "enet_axi_src", base + 0x8900, 28); | |
| 543 | + clks[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_gate("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28); | |
| 544 | + clks[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_gate("ahb_cg", "ahb_src", base + 0x9000, 28); | |
| 545 | + clks[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_gate("dram_phym_cg", "dram_phym_src", base + 0x9800, 28); | |
| 546 | + clks[IMX7D_DRAM_ROOT_CG] = imx_clk_gate("dram_cg", "dram_src", base + 0x9880, 28); | |
| 547 | + clks[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_gate("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28); | |
| 548 | + clks[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_gate("dram_alt_cg", "dram_alt_src", base + 0xa080, 28); | |
| 549 | + clks[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_gate("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28); | |
| 550 | + clks[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_gate("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28); | |
| 551 | + clks[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_gate("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28); | |
| 552 | + clks[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_gate("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28); | |
| 553 | + clks[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_gate("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28); | |
| 554 | + clks[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_gate("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28); | |
| 555 | + clks[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_gate("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28); | |
| 556 | + clks[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_gate("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28); | |
| 557 | + clks[IMX7D_SAI1_ROOT_CG] = imx_clk_gate("sai1_cg", "sai1_src", base + 0xa500, 28); | |
| 558 | + clks[IMX7D_SAI2_ROOT_CG] = imx_clk_gate("sai2_cg", "sai2_src", base + 0xa580, 28); | |
| 559 | + clks[IMX7D_SAI3_ROOT_CG] = imx_clk_gate("sai3_cg", "sai3_src", base + 0xa600, 28); | |
| 560 | + clks[IMX7D_SPDIF_ROOT_CG] = imx_clk_gate("spdif_cg", "spdif_src", base + 0xa680, 28); | |
| 561 | + clks[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_gate("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28); | |
| 562 | + clks[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_gate("enet1_time_cg", "enet1_time_src", base + 0xa780, 28); | |
| 563 | + clks[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_gate("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28); | |
| 564 | + clks[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_gate("enet2_time_cg", "enet2_time_src", base + 0xa880, 28); | |
| 565 | + clks[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_gate("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28); | |
| 566 | + clks[IMX7D_EIM_ROOT_CG] = imx_clk_gate("eim_cg", "eim_src", base + 0xa980, 28); | |
| 567 | + clks[IMX7D_NAND_ROOT_CG] = imx_clk_gate("nand_cg", "nand_src", base + 0xaa00, 28); | |
| 568 | + clks[IMX7D_QSPI_ROOT_CG] = imx_clk_gate("qspi_cg", "qspi_src", base + 0xaa80, 28); | |
| 569 | + clks[IMX7D_USDHC1_ROOT_CG] = imx_clk_gate("usdhc1_cg", "usdhc1_src", base + 0xab00, 28); | |
| 570 | + clks[IMX7D_USDHC2_ROOT_CG] = imx_clk_gate("usdhc2_cg", "usdhc2_src", base + 0xab80, 28); | |
| 571 | + clks[IMX7D_USDHC3_ROOT_CG] = imx_clk_gate("usdhc3_cg", "usdhc3_src", base + 0xac00, 28); | |
| 572 | + clks[IMX7D_CAN1_ROOT_CG] = imx_clk_gate("can1_cg", "can1_src", base + 0xac80, 28); | |
| 573 | + clks[IMX7D_CAN2_ROOT_CG] = imx_clk_gate("can2_cg", "can2_src", base + 0xad00, 28); | |
| 574 | + clks[IMX7D_I2C1_ROOT_CG] = imx_clk_gate("i2c1_cg", "i2c1_src", base + 0xad80, 28); | |
| 575 | + clks[IMX7D_I2C2_ROOT_CG] = imx_clk_gate("i2c2_cg", "i2c2_src", base + 0xae00, 28); | |
| 576 | + clks[IMX7D_I2C3_ROOT_CG] = imx_clk_gate("i2c3_cg", "i2c3_src", base + 0xae80, 28); | |
| 577 | + clks[IMX7D_I2C4_ROOT_CG] = imx_clk_gate("i2c4_cg", "i2c4_src", base + 0xaf00, 28); | |
| 578 | + clks[IMX7D_UART1_ROOT_CG] = imx_clk_gate("uart1_cg", "uart1_src", base + 0xaf80, 28); | |
| 579 | + clks[IMX7D_UART2_ROOT_CG] = imx_clk_gate("uart2_cg", "uart2_src", base + 0xb000, 28); | |
| 580 | + clks[IMX7D_UART3_ROOT_CG] = imx_clk_gate("uart3_cg", "uart3_src", base + 0xb080, 28); | |
| 581 | + clks[IMX7D_UART4_ROOT_CG] = imx_clk_gate("uart4_cg", "uart4_src", base + 0xb100, 28); | |
| 582 | + clks[IMX7D_UART5_ROOT_CG] = imx_clk_gate("uart5_cg", "uart5_src", base + 0xb180, 28); | |
| 583 | + clks[IMX7D_UART6_ROOT_CG] = imx_clk_gate("uart6_cg", "uart6_src", base + 0xb200, 28); | |
| 584 | + clks[IMX7D_UART7_ROOT_CG] = imx_clk_gate("uart7_cg", "uart7_src", base + 0xb280, 28); | |
| 585 | + clks[IMX7D_ECSPI1_ROOT_CG] = imx_clk_gate("ecspi1_cg", "ecspi1_src", base + 0xb300, 28); | |
| 586 | + clks[IMX7D_ECSPI2_ROOT_CG] = imx_clk_gate("ecspi2_cg", "ecspi2_src", base + 0xb380, 28); | |
| 587 | + clks[IMX7D_ECSPI3_ROOT_CG] = imx_clk_gate("ecspi3_cg", "ecspi3_src", base + 0xb400, 28); | |
| 588 | + clks[IMX7D_ECSPI4_ROOT_CG] = imx_clk_gate("ecspi4_cg", "ecspi4_src", base + 0xb480, 28); | |
| 589 | + clks[IMX7D_PWM1_ROOT_CG] = imx_clk_gate("pwm1_cg", "pwm1_src", base + 0xb500, 28); | |
| 590 | + clks[IMX7D_PWM2_ROOT_CG] = imx_clk_gate("pwm2_cg", "pwm2_src", base + 0xb580, 28); | |
| 591 | + clks[IMX7D_PWM3_ROOT_CG] = imx_clk_gate("pwm3_cg", "pwm3_src", base + 0xb600, 28); | |
| 592 | + clks[IMX7D_PWM4_ROOT_CG] = imx_clk_gate("pwm4_cg", "pwm4_src", base + 0xb680, 28); | |
| 593 | + clks[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_gate("flextimer1_cg", "flextimer1_src", base + 0xb700, 28); | |
| 594 | + clks[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_gate("flextimer2_cg", "flextimer2_src", base + 0xb780, 28); | |
| 595 | + clks[IMX7D_SIM1_ROOT_CG] = imx_clk_gate("sim1_cg", "sim1_src", base + 0xb800, 28); | |
| 596 | + clks[IMX7D_SIM2_ROOT_CG] = imx_clk_gate("sim2_cg", "sim2_src", base + 0xb880, 28); | |
| 597 | + clks[IMX7D_GPT1_ROOT_CG] = imx_clk_gate("gpt1_cg", "gpt1_src", base + 0xb900, 28); | |
| 598 | + clks[IMX7D_GPT2_ROOT_CG] = imx_clk_gate("gpt2_cg", "gpt2_src", base + 0xb980, 28); | |
| 599 | + clks[IMX7D_GPT3_ROOT_CG] = imx_clk_gate("gpt3_cg", "gpt3_src", base + 0xbA00, 28); | |
| 600 | + clks[IMX7D_GPT4_ROOT_CG] = imx_clk_gate("gpt4_cg", "gpt4_src", base + 0xbA80, 28); | |
| 601 | + clks[IMX7D_TRACE_ROOT_CG] = imx_clk_gate("trace_cg", "trace_src", base + 0xbb00, 28); | |
| 602 | + clks[IMX7D_WDOG_ROOT_CG] = imx_clk_gate("wdog_cg", "wdog_src", base + 0xbb80, 28); | |
| 603 | + clks[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_gate("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28); | |
| 604 | + clks[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_gate("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28); | |
| 605 | + clks[IMX7D_WRCLK_ROOT_CG] = imx_clk_gate("wrclk_cg", "wrclk_src", base + 0xbd00, 28); | |
| 606 | + clks[IMX7D_CLKO1_ROOT_CG] = imx_clk_gate("clko1_cg", "clko1_src", base + 0xbd80, 28); | |
| 607 | + clks[IMX7D_CLKO2_ROOT_CG] = imx_clk_gate("clko2_cg", "clko2_src", base + 0xbe00, 28); | |
| 608 | + | |
| 609 | + clks[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_divider("axi_pre_div", "axi_cg", base + 0x8800, 16, 3); | |
| 610 | + clks[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_divider("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3); | |
| 611 | + clks[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_divider("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3); | |
| 612 | + clks[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_divider("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3); | |
| 613 | + clks[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_divider("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3); | |
| 614 | + clks[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3); | |
| 615 | + clks[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3); | |
| 616 | + clks[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_divider("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3); | |
| 617 | + clks[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_divider("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3); | |
| 618 | + clks[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_divider("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3); | |
| 619 | + clks[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3); | |
| 620 | + clks[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3); | |
| 621 | + clks[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3); | |
| 622 | + clks[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3); | |
| 623 | + clks[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_divider("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3); | |
| 624 | + clks[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_divider("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3); | |
| 625 | + clks[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_divider("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3); | |
| 626 | + clks[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_divider("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3); | |
| 627 | + clks[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_divider("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3); | |
| 628 | + clks[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_divider("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3); | |
| 629 | + clks[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3); | |
| 630 | + clks[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_divider("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3); | |
| 631 | + clks[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3); | |
| 632 | + clks[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_divider("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3); | |
| 633 | + clks[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_divider("eim_pre_div", "eim_cg", base + 0xa980, 16, 3); | |
| 634 | + clks[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_divider("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3); | |
| 635 | + clks[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_divider("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3); | |
| 636 | + clks[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_divider("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3); | |
| 637 | + clks[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_divider("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3); | |
| 638 | + clks[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_divider("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3); | |
| 639 | + clks[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_divider("can1_pre_div", "can1_cg", base + 0xac80, 16, 3); | |
| 640 | + clks[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_divider("can2_pre_div", "can2_cg", base + 0xad00, 16, 3); | |
| 641 | + clks[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_divider("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3); | |
| 642 | + clks[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_divider("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3); | |
| 643 | + clks[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_divider("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3); | |
| 644 | + clks[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_divider("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3); | |
| 645 | + clks[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_divider("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3); | |
| 646 | + clks[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_divider("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3); | |
| 647 | + clks[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_divider("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3); | |
| 648 | + clks[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_divider("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3); | |
| 649 | + clks[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_divider("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3); | |
| 650 | + clks[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_divider("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3); | |
| 651 | + clks[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_divider("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3); | |
| 652 | + clks[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_divider("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3); | |
| 653 | + clks[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_divider("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3); | |
| 654 | + clks[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_divider("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3); | |
| 655 | + clks[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_divider("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3); | |
| 656 | + clks[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_divider("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3); | |
| 657 | + clks[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_divider("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3); | |
| 658 | + clks[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_divider("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3); | |
| 659 | + clks[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_divider("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3); | |
| 660 | + clks[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_divider("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3); | |
| 661 | + clks[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_divider("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3); | |
| 662 | + clks[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_divider("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3); | |
| 663 | + clks[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_divider("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3); | |
| 664 | + clks[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_divider("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3); | |
| 665 | + clks[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_divider("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3); | |
| 666 | + clks[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_divider("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3); | |
| 667 | + clks[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_divider("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3); | |
| 668 | + clks[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_divider("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3); | |
| 669 | + clks[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_divider("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3); | |
| 670 | + clks[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_divider("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3); | |
| 671 | + clks[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_divider("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3); | |
| 672 | + clks[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_divider("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3); | |
| 673 | + clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3); | |
| 674 | + clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3); | |
| 675 | + | |
| 676 | + clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3); | |
| 677 | + clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); | |
| 678 | + clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3); | |
| 679 | + clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6); | |
| 680 | + clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6); | |
| 681 | + clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6); | |
| 682 | + clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6); | |
| 683 | + clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider("ahb_post_div", "ahb_pre_div", base + 0x9000, 0, 6); | |
| 684 | + clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider("dram_post_div", "dram_cg", base + 0x9880, 0, 3); | |
| 685 | + clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3); | |
| 686 | + clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3); | |
| 687 | + clks[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_divider("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6); | |
| 688 | + clks[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_divider("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6); | |
| 689 | + clks[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_divider("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6); | |
| 690 | + clks[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_divider("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6); | |
| 691 | + clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6); | |
| 692 | + clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6); | |
| 693 | + clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6); | |
| 694 | + clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider("mipi_dphy_post_div", "mipi_csi_dphy_div", base + 0xa480, 0, 6); | |
| 695 | + clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6); | |
| 696 | + clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6); | |
| 697 | + clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6); | |
| 698 | + clks[IMX7D_SPDIF_ROOT_DIV] = imx_clk_divider("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6); | |
| 699 | + clks[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_divider("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6); | |
| 700 | + clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6); | |
| 701 | + clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6); | |
| 702 | + clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6); | |
| 703 | + clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6); | |
| 704 | + clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6); | |
| 705 | + clks[IMX7D_NAND_ROOT_DIV] = imx_clk_divider("nand_post_div", "nand_pre_div", base + 0xaa00, 0, 6); | |
| 706 | + clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6); | |
| 707 | + clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6); | |
| 708 | + clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6); | |
| 709 | + clks[IMX7D_USDHC3_ROOT_DIV] = imx_clk_divider("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6); | |
| 710 | + clks[IMX7D_CAN1_ROOT_DIV] = imx_clk_divider("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6); | |
| 711 | + clks[IMX7D_CAN2_ROOT_DIV] = imx_clk_divider("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6); | |
| 712 | + clks[IMX7D_I2C1_ROOT_DIV] = imx_clk_divider("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6); | |
| 713 | + clks[IMX7D_I2C2_ROOT_DIV] = imx_clk_divider("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6); | |
| 714 | + clks[IMX7D_I2C3_ROOT_DIV] = imx_clk_divider("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6); | |
| 715 | + clks[IMX7D_I2C4_ROOT_DIV] = imx_clk_divider("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6); | |
| 716 | + clks[IMX7D_UART1_ROOT_DIV] = imx_clk_divider("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6); | |
| 717 | + clks[IMX7D_UART2_ROOT_DIV] = imx_clk_divider("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6); | |
| 718 | + clks[IMX7D_UART3_ROOT_DIV] = imx_clk_divider("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6); | |
| 719 | + clks[IMX7D_UART4_ROOT_DIV] = imx_clk_divider("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6); | |
| 720 | + clks[IMX7D_UART5_ROOT_DIV] = imx_clk_divider("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6); | |
| 721 | + clks[IMX7D_UART6_ROOT_DIV] = imx_clk_divider("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6); | |
| 722 | + clks[IMX7D_UART7_ROOT_DIV] = imx_clk_divider("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6); | |
| 723 | + clks[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_divider("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6); | |
| 724 | + clks[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_divider("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6); | |
| 725 | + clks[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_divider("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6); | |
| 726 | + clks[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_divider("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6); | |
| 727 | + clks[IMX7D_PWM1_ROOT_DIV] = imx_clk_divider("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6); | |
| 728 | + clks[IMX7D_PWM2_ROOT_DIV] = imx_clk_divider("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6); | |
| 729 | + clks[IMX7D_PWM3_ROOT_DIV] = imx_clk_divider("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6); | |
| 730 | + clks[IMX7D_PWM4_ROOT_DIV] = imx_clk_divider("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6); | |
| 731 | + clks[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_divider("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6); | |
| 732 | + clks[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_divider("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6); | |
| 733 | + clks[IMX7D_SIM1_ROOT_DIV] = imx_clk_divider("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6); | |
| 734 | + clks[IMX7D_SIM2_ROOT_DIV] = imx_clk_divider("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6); | |
| 735 | + clks[IMX7D_GPT1_ROOT_DIV] = imx_clk_divider("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6); | |
| 736 | + clks[IMX7D_GPT2_ROOT_DIV] = imx_clk_divider("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6); | |
| 737 | + clks[IMX7D_GPT3_ROOT_DIV] = imx_clk_divider("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6); | |
| 738 | + clks[IMX7D_GPT4_ROOT_DIV] = imx_clk_divider("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6); | |
| 739 | + clks[IMX7D_TRACE_ROOT_DIV] = imx_clk_divider("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6); | |
| 740 | + clks[IMX7D_WDOG_ROOT_DIV] = imx_clk_divider("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6); | |
| 741 | + clks[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_divider("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6); | |
| 742 | + clks[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_divider("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6); | |
| 743 | + clks[IMX7D_WRCLK_ROOT_DIV] = imx_clk_divider("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6); | |
| 744 | + clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6); | |
| 745 | + clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6); | |
| 746 | + | |
| 747 | + clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0); | |
| 748 | + clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate2("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0); | |
| 749 | + clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate2("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0); | |
| 750 | + clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate2("main_axi_root_clk", "axi_post_div", base + 0x4040, 0); | |
| 751 | + clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate2("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0); | |
| 752 | + clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate2("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0); | |
| 753 | + clks[IMX7D_OCRAM_CLK] = imx_clk_gate2("ocram_clk", "axi_post_div", base + 0x4110, 0); | |
| 754 | + clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate2("ocram_s_clk", "ahb_post_div", base + 0x4120, 0); | |
| 755 | + clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate2("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0); | |
| 756 | + clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate2("ahb_root_clk", "ahb_post_div", base + 0x4200, 0); | |
| 757 | + clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate2("dram_root_clk", "dram_post_div", base + 0x4130, 0); | |
| 758 | + clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate2("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0); | |
| 759 | + clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate2("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0); | |
| 760 | + clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate2("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0); | |
| 761 | + clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate2("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0); | |
| 762 | + clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate2("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0); | |
| 763 | + clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate2("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0); | |
| 764 | + clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate2("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0); | |
| 765 | + clks[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_gate2("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0); | |
| 766 | + clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate2("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0); | |
| 767 | + clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate2("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0); | |
| 768 | + clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate2("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0); | |
| 769 | + clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0); | |
| 770 | + clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0); | |
| 771 | + clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0); | |
| 772 | + clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate2("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0); | |
| 773 | + clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate2("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0); | |
| 774 | + clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate2("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0); | |
| 775 | + clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate2("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0); | |
| 776 | + clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0); | |
| 777 | + clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate2("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0); | |
| 778 | + clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate2("eim_root_clk", "eim_post_div", base + 0x4160, 0); | |
| 779 | + clks[IMX7D_NAND_ROOT_CLK] = imx_clk_gate2("nand_root_clk", "nand_post_div", base + 0x4140, 0); | |
| 780 | + clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate2("qspi_root_clk", "qspi_post_div", base + 0x4150, 0); | |
| 781 | + clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate2("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0); | |
| 782 | + clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate2("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0); | |
| 783 | + clks[IMX7D_USDHC3_ROOT_CLK] = imx_clk_gate2("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0); | |
| 784 | + clks[IMX7D_CAN1_ROOT_CLK] = imx_clk_gate2("can1_root_clk", "can1_post_div", base + 0x4740, 0); | |
| 785 | + clks[IMX7D_CAN2_ROOT_CLK] = imx_clk_gate2("can2_root_clk", "can2_post_div", base + 0x4750, 0); | |
| 786 | + clks[IMX7D_I2C1_ROOT_CLK] = imx_clk_gate2("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0); | |
| 787 | + clks[IMX7D_I2C2_ROOT_CLK] = imx_clk_gate2("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0); | |
| 788 | + clks[IMX7D_I2C3_ROOT_CLK] = imx_clk_gate2("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0); | |
| 789 | + clks[IMX7D_I2C4_ROOT_CLK] = imx_clk_gate2("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0); | |
| 790 | + clks[IMX7D_UART1_ROOT_CLK] = imx_clk_gate2("uart1_root_clk", "uart1_post_div", base + 0x4940, 0); | |
| 791 | + clks[IMX7D_UART2_ROOT_CLK] = imx_clk_gate2("uart2_root_clk", "uart2_post_div", base + 0x4950, 0); | |
| 792 | + clks[IMX7D_UART3_ROOT_CLK] = imx_clk_gate2("uart3_root_clk", "uart3_post_div", base + 0x4960, 0); | |
| 793 | + clks[IMX7D_UART4_ROOT_CLK] = imx_clk_gate2("uart4_root_clk", "uart4_post_div", base + 0x4970, 0); | |
| 794 | + clks[IMX7D_UART5_ROOT_CLK] = imx_clk_gate2("uart5_root_clk", "uart5_post_div", base + 0x4980, 0); | |
| 795 | + clks[IMX7D_UART6_ROOT_CLK] = imx_clk_gate2("uart6_root_clk", "uart6_post_div", base + 0x4990, 0); | |
| 796 | + clks[IMX7D_UART7_ROOT_CLK] = imx_clk_gate2("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0); | |
| 797 | + clks[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_gate2("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0); | |
| 798 | + clks[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_gate2("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0); | |
| 799 | + clks[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_gate2("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0); | |
| 800 | + clks[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_gate2("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0); | |
| 801 | + clks[IMX7D_PWM1_ROOT_CLK] = imx_clk_gate2("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0); | |
| 802 | + clks[IMX7D_PWM2_ROOT_CLK] = imx_clk_gate2("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0); | |
| 803 | + clks[IMX7D_PWM3_ROOT_CLK] = imx_clk_gate2("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0); | |
| 804 | + clks[IMX7D_PWM4_ROOT_CLK] = imx_clk_gate2("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0); | |
| 805 | + clks[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_gate2("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0); | |
| 806 | + clks[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_gate2("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0); | |
| 807 | + clks[IMX7D_SIM1_ROOT_CLK] = imx_clk_gate2("sim1_root_clk", "sim1_post_div", base + 0x4900, 0); | |
| 808 | + clks[IMX7D_SIM2_ROOT_CLK] = imx_clk_gate2("sim2_root_clk", "sim2_post_div", base + 0x4910, 0); | |
| 809 | + clks[IMX7D_GPT1_ROOT_CLK] = imx_clk_gate2("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0); | |
| 810 | + clks[IMX7D_GPT2_ROOT_CLK] = imx_clk_gate2("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0); | |
| 811 | + clks[IMX7D_GPT3_ROOT_CLK] = imx_clk_gate2("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0); | |
| 812 | + clks[IMX7D_GPT4_ROOT_CLK] = imx_clk_gate2("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0); | |
| 813 | + clks[IMX7D_TRACE_ROOT_CLK] = imx_clk_gate2("trace_root_clk", "trace_post_div", base + 0x4300, 0); | |
| 814 | + clks[IMX7D_WDOG1_ROOT_CLK] = imx_clk_gate2("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0); | |
| 815 | + clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate2("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0); | |
| 816 | + clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate2("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0); | |
| 817 | + clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate2("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0); | |
| 818 | + clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); | |
| 819 | + clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); | |
| 820 | + clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); | |
| 821 | + | |
| 822 | + clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); | |
| 823 | + | |
| 824 | + for (i = 0; i < ARRAY_SIZE(clks); i++) | |
| 825 | + if (IS_ERR(clks[i])) | |
| 826 | + pr_err("i.MX7D clk %d: register failed with %ld\n", | |
| 827 | + i, PTR_ERR(clks[i])); | |
| 828 | + | |
| 829 | + clk_data.clks = clks; | |
| 830 | + clk_data.clk_num = ARRAY_SIZE(clks); | |
| 831 | + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | |
| 832 | + | |
| 833 | + /* TO BE FIXED LATER | |
| 834 | + * Enable all clock to bring up imx7, otherwise system will be halt and block | |
| 835 | + * the other part upstream Because imx7d clock design changed, clock framework | |
| 836 | + * need do a little modify. | |
| 837 | + * Dong Aisheng is working on this. After that, this part need be changed. | |
| 838 | + */ | |
| 839 | + for (i = 0; i < IMX7D_CLK_END; i++) | |
| 840 | + clk_prepare_enable(clks[i]); | |
| 841 | + | |
| 842 | + /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */ | |
| 843 | + clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); | |
| 844 | + | |
| 845 | + /* | |
| 846 | + * init enet clock source: | |
| 847 | + * AXI clock source is 250MHz | |
| 848 | + * Phy refrence clock is 25MHz | |
| 849 | + * 1588 time clock source is 100MHz | |
| 850 | + */ | |
| 851 | + clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]); | |
| 852 | + clk_set_parent(clks[IMX7D_ENET_PHY_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_25M_CLK]); | |
| 853 | + clk_set_parent(clks[IMX7D_ENET1_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]); | |
| 854 | + clk_set_parent(clks[IMX7D_ENET2_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]); | |
| 855 | + | |
| 856 | + /* set uart module clock's parent clock source that must be great then 80MHz */ | |
| 857 | + clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); | |
| 858 | + | |
| 859 | +} | |
| 860 | +CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init); | |
File renamed without changes.
| @@ -6,8 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/err.h> |
| 7 | 7 | |
| 8 | 8 | #include "clk.h" |
| 9 | −#include "common.h" | |
| 10 | −#include "hardware.h" | |
| 11 | 9 | |
| 12 | 10 | /** |
| 13 | 11 | * pll v1 |
| @@ -26,13 +24,29 @@ · 12 unmodified lines | ||
| 26 | 24 | struct clk_pllv1 { |
| 27 | 25 | struct clk_hw hw; |
| 28 | 26 | void __iomem *base; |
| 27 | + enum imx_pllv1_type type; | |
| 29 | 28 | }; |
| 30 | 29 | |
| 31 | 30 | #define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk)) |
| 32 | 31 | |
| 33 | −static inline bool mfn_is_negative(unsigned int mfn) | |
| 32 | +static inline bool is_imx1_pllv1(struct clk_pllv1 *pll) | |
| 34 | 33 | { |
| 35 | − return !cpu_is_mx1() && !cpu_is_mx21() && (mfn & MFN_SIGN); | |
| 34 | + return pll->type == IMX_PLLV1_IMX1; | |
| 35 | +} | |
| 36 | + | |
| 37 | +static inline bool is_imx21_pllv1(struct clk_pllv1 *pll) | |
| 38 | +{ | |
| 39 | + return pll->type == IMX_PLLV1_IMX21; | |
| 40 | +} | |
| 41 | + | |
| 42 | +static inline bool is_imx27_pllv1(struct clk_pllv1 *pll) | |
| 43 | +{ | |
| 44 | + return pll->type == IMX_PLLV1_IMX27; | |
| 45 | +} | |
| 46 | + | |
| 47 | +static inline bool mfn_is_negative(struct clk_pllv1 *pll, unsigned int mfn) | |
| 48 | +{ | |
| 49 | + return !is_imx1_pllv1(pll) && !is_imx21_pllv1(pll) && (mfn & MFN_SIGN); | |
| 36 | 50 | } |
| 37 | 51 | |
| 38 | 52 | static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, |
| @@ -71,8 +85,8 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, · 32 unmodified lines | ||
| 71 | 85 | * 2's complements number. |
| 72 | 86 | * On i.MX27 the bit 9 is the sign bit. |
| 73 | 87 | */ |
| 74 | − if (mfn_is_negative(mfn)) { | |
| 75 | − if (cpu_is_mx27()) | |
| 88 | + if (mfn_is_negative(pll, mfn)) { | |
| 89 | + if (is_imx27_pllv1(pll)) | |
| 76 | 90 | mfn_abs = mfn & MFN_MASK; |
| 77 | 91 | else |
| 78 | 92 | mfn_abs = BIT(MFN_BITS) - mfn; |
| @@ -85,7 +99,7 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, · 6 unmodified lines | ||
| 85 | 99 | |
| 86 | 100 | do_div(ll, mfd + 1); |
| 87 | 101 | |
| 88 | − if (mfn_is_negative(mfn)) | |
| 102 | + if (mfn_is_negative(pll, mfn)) | |
| 89 | 103 | ll = -ll; |
| 90 | 104 | |
| 91 | 105 | ll = (rate * mfi) + ll; |
| @@ -97,8 +111,8 @@ static struct clk_ops clk_pllv1_ops = { · 5 unmodified lines | ||
| 97 | 111 | .recalc_rate = clk_pllv1_recalc_rate, |
| 98 | 112 | }; |
| 99 | 113 | |
| 100 | −struct clk *imx_clk_pllv1(const char *name, const char *parent, | |
| 101 | − void __iomem *base) | |
| 114 | +struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, | |
| 115 | + const char *parent, void __iomem *base) | |
| 102 | 116 | { |
| 103 | 117 | struct clk_pllv1 *pll; |
| 104 | 118 | struct clk *clk; |
| @@ -109,6 +123,7 @@ struct clk *imx_clk_pllv1(const char *name, const char *parent, · 4 unmodified lines | ||
| 109 | 123 | return ERR_PTR(-ENOMEM); |
| 110 | 124 | |
| 111 | 125 | pll->base = base; |
| 126 | + pll->type = type; | |
| 112 | 127 | |
| 113 | 128 | init.name = name; |
| 114 | 129 | init.ops = &clk_pllv1_ops; |
File renamed without changes.
| @@ -24,12 +24,14 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #define BM_PLL_POWER (0x1 << 12) |
| 26 | 26 | #define BM_PLL_LOCK (0x1 << 31) |
| 27 | +#define IMX7_ENET_PLL_POWER (0x1 << 5) | |
| 27 | 28 | |
| 28 | 29 | /** |
| 29 | 30 | * struct clk_pllv3 - IMX PLL clock version 3 |
| 30 | 31 | * @clk_hw: clock source |
| 31 | 32 | * @base: base address of PLL registers |
| 32 | 33 | * @powerup_set: set POWER bit to power up the PLL |
| 34 | + * @powerdown: pll powerdown offset bit | |
| 33 | 35 | * @div_mask: mask of divider bits |
| 34 | 36 | * @div_shift: shift of divider bits |
| 35 | 37 | * |
| @@ -40,6 +42,7 @@ struct clk_pllv3 { · 4 unmodified lines | ||
| 40 | 42 | struct clk_hw hw; |
| 41 | 43 | void __iomem *base; |
| 42 | 44 | bool powerup_set; |
| 45 | + u32 powerdown; | |
| 43 | 46 | u32 div_mask; |
| 44 | 47 | u32 div_shift; |
| 45 | 48 | }; |
| @@ -49,7 +52,7 @@ struct clk_pllv3 { · 3 unmodified lines | ||
| 49 | 52 | static int clk_pllv3_wait_lock(struct clk_pllv3 *pll) |
| 50 | 53 | { |
| 51 | 54 | unsigned long timeout = jiffies + msecs_to_jiffies(10); |
| 52 | − u32 val = readl_relaxed(pll->base) & BM_PLL_POWER; | |
| 55 | + u32 val = readl_relaxed(pll->base) & pll->powerdown; | |
| 53 | 56 | |
| 54 | 57 | /* No need to wait for lock when pll is not powered up */ |
| 55 | 58 | if ((pll->powerup_set && !val) || (!pll->powerup_set && val)) |
| @@ -215,7 +218,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, · 159 unmodified lines | ||
| 215 | 218 | unsigned long max_rate = parent_rate * 54; |
| 216 | 219 | u32 div; |
| 217 | 220 | u32 mfn, mfd = 1000000; |
| 218 | − s64 temp64; | |
| 221 | + u64 temp64; | |
| 219 | 222 | |
| 220 | 223 | if (rate > max_rate) |
| 221 | 224 | rate = max_rate; |
| @@ -239,7 +242,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, · 17 unmodified lines | ||
| 239 | 242 | unsigned long max_rate = parent_rate * 54; |
| 240 | 243 | u32 val, div; |
| 241 | 244 | u32 mfn, mfd = 1000000; |
| 242 | − s64 temp64; | |
| 245 | + u64 temp64; | |
| 243 | 246 | |
| 244 | 247 | if (rate < min_rate || rate > max_rate) |
| 245 | 248 | return -EINVAL; |
| @@ -293,6 +296,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, · 47 unmodified lines | ||
| 293 | 296 | if (!pll) |
| 294 | 297 | return ERR_PTR(-ENOMEM); |
| 295 | 298 | |
| 299 | + pll->powerdown = BM_PLL_POWER; | |
| 300 | + | |
| 296 | 301 | switch (type) { |
| 297 | 302 | case IMX_PLLV3_SYS: |
| 298 | 303 | ops = &clk_pllv3_sys_ops; |
| @@ -306,6 +311,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, · 7 unmodified lines | ||
| 306 | 311 | case IMX_PLLV3_AV: |
| 307 | 312 | ops = &clk_pllv3_av_ops; |
| 308 | 313 | break; |
| 314 | + case IMX_PLLV3_ENET_IMX7: | |
| 315 | + pll->powerdown = IMX7_ENET_PLL_POWER; | |
| 309 | 316 | case IMX_PLLV3_ENET: |
| 310 | 317 | ops = &clk_pllv3_enet_ops; |
| 311 | 318 | break; |
| @@ -118,6 +118,7 @@ static struct clk_onecell_data clk_data; · 117 unmodified lines | ||
| 118 | 118 | static unsigned int const clks_init_on[] __initconst = { |
| 119 | 119 | VF610_CLK_SYS_BUS, |
| 120 | 120 | VF610_CLK_DDR_SEL, |
| 121 | + VF610_CLK_DAP, | |
| 121 | 122 | }; |
| 122 | 123 | |
| 123 | 124 | static struct clk * __init vf610_get_fixed_clock( |
| @@ -272,6 +273,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) · 148 unmodified lines | ||
| 272 | 273 | |
| 273 | 274 | clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6)); |
| 274 | 275 | clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7)); |
| 276 | + clk[VF610_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(6)); | |
| 277 | + clk[VF610_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(7)); | |
| 275 | 278 | |
| 276 | 279 | clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12)); |
| 277 | 280 | clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13)); |
| @@ -383,6 +386,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) · 105 unmodified lines | ||
| 383 | 386 | clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2)); |
| 384 | 387 | |
| 385 | 388 | clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7)); |
| 389 | + clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24); | |
| 386 | 390 | |
| 387 | 391 | imx_check_clocks(clk, ARRAY_SIZE(clk)); |
| 388 | 392 | |
File renamed without changes.
| @@ -10,8 +10,17 @@ void imx_check_clocks(struct clk *clks[], unsigned int count); · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | extern void imx_cscmr1_fixup(u32 *val); |
| 12 | 12 | |
| 13 | −struct clk *imx_clk_pllv1(const char *name, const char *parent, | |
| 14 | − void __iomem *base); | |
| 13 | +enum imx_pllv1_type { | |
| 14 | + IMX_PLLV1_IMX1, | |
| 15 | + IMX_PLLV1_IMX21, | |
| 16 | + IMX_PLLV1_IMX25, | |
| 17 | + IMX_PLLV1_IMX27, | |
| 18 | + IMX_PLLV1_IMX31, | |
| 19 | + IMX_PLLV1_IMX35, | |
| 20 | +}; | |
| 21 | + | |
| 22 | +struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, | |
| 23 | + const char *parent, void __iomem *base); | |
| 15 | 24 | |
| 16 | 25 | struct clk *imx_clk_pllv2(const char *name, const char *parent, |
| 17 | 26 | void __iomem *base); |
| @@ -23,6 +32,7 @@ enum imx_pllv3_type { · 5 unmodified lines | ||
| 23 | 32 | IMX_PLLV3_USB_VF610, |
| 24 | 33 | IMX_PLLV3_AV, |
| 25 | 34 | IMX_PLLV3_ENET, |
| 35 | + IMX_PLLV3_ENET_IMX7, | |
| 26 | 36 | }; |
| 27 | 37 | |
| 28 | 38 | struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, |
| @@ -353,6 +353,34 @@ static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw) · 352 unmodified lines | ||
| 353 | 353 | PARENTS(clk_pxa27x_memory) = { "osc_13mhz", "system_bus", "run" }; |
| 354 | 354 | MUX_RO_RATE_RO_OPS(clk_pxa27x_memory, "memory"); |
| 355 | 355 | |
| 356 | +#define DUMMY_CLK(_con_id, _dev_id, _parent) \ | |
| 357 | + { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent } | |
| 358 | +struct dummy_clk { | |
| 359 | + const char *con_id; | |
| 360 | + const char *dev_id; | |
| 361 | + const char *parent; | |
| 362 | +}; | |
| 363 | +static struct dummy_clk dummy_clks[] __initdata = { | |
| 364 | + DUMMY_CLK(NULL, "pxa27x-gpio", "osc_32_768khz"), | |
| 365 | + DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"), | |
| 366 | + DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"), | |
| 367 | +}; | |
| 368 | + | |
| 369 | +static void __init pxa27x_dummy_clocks_init(void) | |
| 370 | +{ | |
| 371 | + struct clk *clk; | |
| 372 | + struct dummy_clk *d; | |
| 373 | + const char *name; | |
| 374 | + int i; | |
| 375 | + | |
| 376 | + for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) { | |
| 377 | + d = &dummy_clks[i]; | |
| 378 | + name = d->dev_id ? d->dev_id : d->con_id; | |
| 379 | + clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1); | |
| 380 | + clk_register_clkdev(clk, d->con_id, d->dev_id); | |
| 381 | + } | |
| 382 | +} | |
| 383 | + | |
| 356 | 384 | static void __init pxa27x_base_clocks_init(void) |
| 357 | 385 | { |
| 358 | 386 | pxa27x_register_plls(); |
| @@ -362,12 +390,12 @@ static void __init pxa27x_base_clocks_init(void) · 3 unmodified lines | ||
| 362 | 390 | clk_register_clk_pxa27x_lcd_base(); |
| 363 | 391 | } |
| 364 | 392 | |
| 365 | −static int __init pxa27x_clocks_init(void) | |
| 393 | +int __init pxa27x_clocks_init(void) | |
| 366 | 394 | { |
| 367 | 395 | pxa27x_base_clocks_init(); |
| 396 | + pxa27x_dummy_clocks_init(); | |
| 368 | 397 | return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks)); |
| 369 | 398 | } |
| 370 | −postcore_initcall(pxa27x_clocks_init); | |
| 371 | 399 | |
| 372 | 400 | static void __init pxa27x_dt_clocks_init(struct device_node *np) |
| 373 | 401 | { |
| @@ -0,0 +1,2 @@ | ||
| 1 | +obj-y := clk-pll.o | |
| 2 | +obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.o | |
| @@ -0,0 +1,172 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2014 Linaro Ltd. | |
| 3 | + * Copyright (C) 2014 ZTE Corporation. | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/clk-provider.h> | |
| 11 | +#include <linux/err.h> | |
| 12 | +#include <linux/io.h> | |
| 13 | +#include <linux/iopoll.h> | |
| 14 | +#include <linux/slab.h> | |
| 15 | +#include <linux/spinlock.h> | |
| 16 | + | |
| 17 | +#include "clk.h" | |
| 18 | + | |
| 19 | +#define to_clk_zx_pll(_hw) container_of(_hw, struct clk_zx_pll, hw) | |
| 20 | + | |
| 21 | +#define CFG0_CFG1_OFFSET 4 | |
| 22 | +#define LOCK_FLAG BIT(30) | |
| 23 | +#define POWER_DOWN BIT(31) | |
| 24 | + | |
| 25 | +static int rate_to_idx(struct clk_zx_pll *zx_pll, unsigned long rate) | |
| 26 | +{ | |
| 27 | + const struct zx_pll_config *config = zx_pll->lookup_table; | |
| 28 | + int i; | |
| 29 | + | |
| 30 | + for (i = 0; i < zx_pll->count; i++) { | |
| 31 | + if (config[i].rate > rate) | |
| 32 | + return i > 0 ? i - 1 : 0; | |
| 33 | + | |
| 34 | + if (config[i].rate == rate) | |
| 35 | + return i; | |
| 36 | + } | |
| 37 | + | |
| 38 | + return i - 1; | |
| 39 | +} | |
| 40 | + | |
| 41 | +static int hw_to_idx(struct clk_zx_pll *zx_pll) | |
| 42 | +{ | |
| 43 | + const struct zx_pll_config *config = zx_pll->lookup_table; | |
| 44 | + u32 hw_cfg0, hw_cfg1; | |
| 45 | + int i; | |
| 46 | + | |
| 47 | + hw_cfg0 = readl_relaxed(zx_pll->reg_base); | |
| 48 | + hw_cfg1 = readl_relaxed(zx_pll->reg_base + CFG0_CFG1_OFFSET); | |
| 49 | + | |
| 50 | + /* For matching the value in lookup table */ | |
| 51 | + hw_cfg0 &= ~LOCK_FLAG; | |
| 52 | + hw_cfg0 |= POWER_DOWN; | |
| 53 | + | |
| 54 | + for (i = 0; i < zx_pll->count; i++) { | |
| 55 | + if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1) | |
| 56 | + return i; | |
| 57 | + } | |
| 58 | + | |
| 59 | + return -EINVAL; | |
| 60 | +} | |
| 61 | + | |
| 62 | +static unsigned long zx_pll_recalc_rate(struct clk_hw *hw, | |
| 63 | + unsigned long parent_rate) | |
| 64 | +{ | |
| 65 | + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); | |
| 66 | + int idx; | |
| 67 | + | |
| 68 | + idx = hw_to_idx(zx_pll); | |
| 69 | + if (unlikely(idx == -EINVAL)) | |
| 70 | + return 0; | |
| 71 | + | |
| 72 | + return zx_pll->lookup_table[idx].rate; | |
| 73 | +} | |
| 74 | + | |
| 75 | +static long zx_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |
| 76 | + unsigned long *prate) | |
| 77 | +{ | |
| 78 | + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); | |
| 79 | + int idx; | |
| 80 | + | |
| 81 | + idx = rate_to_idx(zx_pll, rate); | |
| 82 | + | |
| 83 | + return zx_pll->lookup_table[idx].rate; | |
| 84 | +} | |
| 85 | + | |
| 86 | +static int zx_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |
| 87 | + unsigned long parent_rate) | |
| 88 | +{ | |
| 89 | + /* Assume current cpu is not running on current PLL */ | |
| 90 | + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); | |
| 91 | + const struct zx_pll_config *config; | |
| 92 | + int idx; | |
| 93 | + | |
| 94 | + idx = rate_to_idx(zx_pll, rate); | |
| 95 | + config = &zx_pll->lookup_table[idx]; | |
| 96 | + | |
| 97 | + writel_relaxed(config->cfg0, zx_pll->reg_base); | |
| 98 | + writel_relaxed(config->cfg1, zx_pll->reg_base + CFG0_CFG1_OFFSET); | |
| 99 | + | |
| 100 | + return 0; | |
| 101 | +} | |
| 102 | + | |
| 103 | +static int zx_pll_enable(struct clk_hw *hw) | |
| 104 | +{ | |
| 105 | + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); | |
| 106 | + u32 reg; | |
| 107 | + | |
| 108 | + reg = readl_relaxed(zx_pll->reg_base); | |
| 109 | + writel_relaxed(reg & ~POWER_DOWN, zx_pll->reg_base); | |
| 110 | + | |
| 111 | + return readl_relaxed_poll_timeout(zx_pll->reg_base, reg, | |
| 112 | + reg & LOCK_FLAG, 0, 100); | |
| 113 | +} | |
| 114 | + | |
| 115 | +static void zx_pll_disable(struct clk_hw *hw) | |
| 116 | +{ | |
| 117 | + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); | |
| 118 | + u32 reg; | |
| 119 | + | |
| 120 | + reg = readl_relaxed(zx_pll->reg_base); | |
| 121 | + writel_relaxed(reg | POWER_DOWN, zx_pll->reg_base); | |
| 122 | +} | |
| 123 | + | |
| 124 | +static int zx_pll_is_enabled(struct clk_hw *hw) | |
| 125 | +{ | |
| 126 | + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); | |
| 127 | + u32 reg; | |
| 128 | + | |
| 129 | + reg = readl_relaxed(zx_pll->reg_base); | |
| 130 | + | |
| 131 | + return !(reg & POWER_DOWN); | |
| 132 | +} | |
| 133 | + | |
| 134 | +static const struct clk_ops zx_pll_ops = { | |
| 135 | + .recalc_rate = zx_pll_recalc_rate, | |
| 136 | + .round_rate = zx_pll_round_rate, | |
| 137 | + .set_rate = zx_pll_set_rate, | |
| 138 | + .enable = zx_pll_enable, | |
| 139 | + .disable = zx_pll_disable, | |
| 140 | + .is_enabled = zx_pll_is_enabled, | |
| 141 | +}; | |
| 142 | + | |
| 143 | +struct clk *clk_register_zx_pll(const char *name, const char *parent_name, | |
| 144 | + unsigned long flags, void __iomem *reg_base, | |
| 145 | + const struct zx_pll_config *lookup_table, int count, spinlock_t *lock) | |
| 146 | +{ | |
| 147 | + struct clk_zx_pll *zx_pll; | |
| 148 | + struct clk *clk; | |
| 149 | + struct clk_init_data init; | |
| 150 | + | |
| 151 | + zx_pll = kzalloc(sizeof(*zx_pll), GFP_KERNEL); | |
| 152 | + if (!zx_pll) | |
| 153 | + return ERR_PTR(-ENOMEM); | |
| 154 | + | |
| 155 | + init.name = name; | |
| 156 | + init.ops = &zx_pll_ops; | |
| 157 | + init.flags = flags; | |
| 158 | + init.parent_names = parent_name ? &parent_name : NULL; | |
| 159 | + init.num_parents = parent_name ? 1 : 0; | |
| 160 | + | |
| 161 | + zx_pll->reg_base = reg_base; | |
| 162 | + zx_pll->lookup_table = lookup_table; | |
| 163 | + zx_pll->count = count; | |
| 164 | + zx_pll->lock = lock; | |
| 165 | + zx_pll->hw.init = &init; | |
| 166 | + | |
| 167 | + clk = clk_register(NULL, &zx_pll->hw); | |
| 168 | + if (IS_ERR(clk)) | |
| 169 | + kfree(zx_pll); | |
| 170 | + | |
| 171 | + return clk; | |
| 172 | +} | |
| @@ -0,0 +1,657 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2014 Linaro Ltd. | |
| 3 | + * Copyright (C) 2014 ZTE Corporation. | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/clk-provider.h> | |
| 11 | +#include <linux/of_address.h> | |
| 12 | +#include <dt-bindings/clock/zx296702-clock.h> | |
| 13 | +#include "clk.h" | |
| 14 | + | |
| 15 | +static DEFINE_SPINLOCK(reg_lock); | |
| 16 | + | |
| 17 | +static void __iomem *topcrm_base; | |
| 18 | +static void __iomem *lsp0crpm_base; | |
| 19 | +static void __iomem *lsp1crpm_base; | |
| 20 | + | |
| 21 | +static struct clk *topclk[ZX296702_TOPCLK_END]; | |
| 22 | +static struct clk *lsp0clk[ZX296702_LSP0CLK_END]; | |
| 23 | +static struct clk *lsp1clk[ZX296702_LSP1CLK_END]; | |
| 24 | + | |
| 25 | +static struct clk_onecell_data topclk_data; | |
| 26 | +static struct clk_onecell_data lsp0clk_data; | |
| 27 | +static struct clk_onecell_data lsp1clk_data; | |
| 28 | + | |
| 29 | +#define CLK_MUX (topcrm_base + 0x04) | |
| 30 | +#define CLK_DIV (topcrm_base + 0x08) | |
| 31 | +#define CLK_EN0 (topcrm_base + 0x0c) | |
| 32 | +#define CLK_EN1 (topcrm_base + 0x10) | |
| 33 | +#define VOU_LOCAL_CLKEN (topcrm_base + 0x68) | |
| 34 | +#define VOU_LOCAL_CLKSEL (topcrm_base + 0x70) | |
| 35 | +#define VOU_LOCAL_DIV2_SET (topcrm_base + 0x74) | |
| 36 | +#define CLK_MUX1 (topcrm_base + 0x8c) | |
| 37 | + | |
| 38 | +#define CLK_SDMMC1 (lsp0crpm_base + 0x0c) | |
| 39 | + | |
| 40 | +#define CLK_UART0 (lsp1crpm_base + 0x20) | |
| 41 | +#define CLK_UART1 (lsp1crpm_base + 0x24) | |
| 42 | +#define CLK_SDMMC0 (lsp1crpm_base + 0x2c) | |
| 43 | + | |
| 44 | +static const struct zx_pll_config pll_a9_config[] = { | |
| 45 | + { .rate = 700000000, .cfg0 = 0x800405d1, .cfg1 = 0x04555555 }, | |
| 46 | + { .rate = 800000000, .cfg0 = 0x80040691, .cfg1 = 0x04aaaaaa }, | |
| 47 | + { .rate = 900000000, .cfg0 = 0x80040791, .cfg1 = 0x04000000 }, | |
| 48 | + { .rate = 1000000000, .cfg0 = 0x80040851, .cfg1 = 0x04555555 }, | |
| 49 | + { .rate = 1100000000, .cfg0 = 0x80040911, .cfg1 = 0x04aaaaaa }, | |
| 50 | + { .rate = 1200000000, .cfg0 = 0x80040a11, .cfg1 = 0x04000000 }, | |
| 51 | +}; | |
| 52 | + | |
| 53 | +static const struct clk_div_table main_hlk_div[] = { | |
| 54 | + { .val = 1, .div = 2, }, | |
| 55 | + { .val = 3, .div = 4, }, | |
| 56 | + { /* sentinel */ } | |
| 57 | +}; | |
| 58 | + | |
| 59 | +static const struct clk_div_table a9_as1_aclk_divider[] = { | |
| 60 | + { .val = 0, .div = 1, }, | |
| 61 | + { .val = 1, .div = 2, }, | |
| 62 | + { .val = 3, .div = 4, }, | |
| 63 | + { /* sentinel */ } | |
| 64 | +}; | |
| 65 | + | |
| 66 | +static const struct clk_div_table sec_wclk_divider[] = { | |
| 67 | + { .val = 0, .div = 1, }, | |
| 68 | + { .val = 1, .div = 2, }, | |
| 69 | + { .val = 3, .div = 4, }, | |
| 70 | + { .val = 5, .div = 6, }, | |
| 71 | + { .val = 7, .div = 8, }, | |
| 72 | + { /* sentinel */ } | |
| 73 | +}; | |
| 74 | + | |
| 75 | +static const char * matrix_aclk_sel[] = { | |
| 76 | + "pll_mm0_198M", | |
| 77 | + "osc", | |
| 78 | + "clk_148M5", | |
| 79 | + "pll_lsp_104M", | |
| 80 | +}; | |
| 81 | + | |
| 82 | +static const char * a9_wclk_sel[] = { | |
| 83 | + "pll_a9", | |
| 84 | + "osc", | |
| 85 | + "clk_500", | |
| 86 | + "clk_250", | |
| 87 | +}; | |
| 88 | + | |
| 89 | +static const char * a9_as1_aclk_sel[] = { | |
| 90 | + "clk_250", | |
| 91 | + "osc", | |
| 92 | + "pll_mm0_396M", | |
| 93 | + "pll_mac_333M", | |
| 94 | +}; | |
| 95 | + | |
| 96 | +static const char * a9_trace_clkin_sel[] = { | |
| 97 | + "clk_74M25", | |
| 98 | + "pll_mm1_108M", | |
| 99 | + "clk_125", | |
| 100 | + "clk_148M5", | |
| 101 | +}; | |
| 102 | + | |
| 103 | +static const char * decppu_aclk_sel[] = { | |
| 104 | + "clk_250", | |
| 105 | + "pll_mm0_198M", | |
| 106 | + "pll_lsp_104M", | |
| 107 | + "pll_audio_294M912", | |
| 108 | +}; | |
| 109 | + | |
| 110 | +static const char * vou_main_wclk_sel[] = { | |
| 111 | + "clk_148M5", | |
| 112 | + "clk_74M25", | |
| 113 | + "clk_27", | |
| 114 | + "pll_mm1_54M", | |
| 115 | +}; | |
| 116 | + | |
| 117 | +static const char * vou_scaler_wclk_sel[] = { | |
| 118 | + "clk_250", | |
| 119 | + "pll_mac_333M", | |
| 120 | + "pll_audio_294M912", | |
| 121 | + "pll_mm0_198M", | |
| 122 | +}; | |
| 123 | + | |
| 124 | +static const char * r2d_wclk_sel[] = { | |
| 125 | + "pll_audio_294M912", | |
| 126 | + "pll_mac_333M", | |
| 127 | + "pll_a9_350M", | |
| 128 | + "pll_mm0_396M", | |
| 129 | +}; | |
| 130 | + | |
| 131 | +static const char * ddr_wclk_sel[] = { | |
| 132 | + "pll_mac_333M", | |
| 133 | + "pll_ddr_266M", | |
| 134 | + "pll_audio_294M912", | |
| 135 | + "pll_mm0_198M", | |
| 136 | +}; | |
| 137 | + | |
| 138 | +static const char * nand_wclk_sel[] = { | |
| 139 | + "pll_lsp_104M", | |
| 140 | + "osc", | |
| 141 | +}; | |
| 142 | + | |
| 143 | +static const char * lsp_26_wclk_sel[] = { | |
| 144 | + "pll_lsp_26M", | |
| 145 | + "osc", | |
| 146 | +}; | |
| 147 | + | |
| 148 | +static const char * vl0_sel[] = { | |
| 149 | + "vou_main_channel_div", | |
| 150 | + "vou_aux_channel_div", | |
| 151 | +}; | |
| 152 | + | |
| 153 | +static const char * hdmi_sel[] = { | |
| 154 | + "vou_main_channel_wclk", | |
| 155 | + "vou_aux_channel_wclk", | |
| 156 | +}; | |
| 157 | + | |
| 158 | +static const char * sdmmc0_wclk_sel[] = { | |
| 159 | + "lsp1_104M_wclk", | |
| 160 | + "lsp1_26M_wclk", | |
| 161 | +}; | |
| 162 | + | |
| 163 | +static const char * sdmmc1_wclk_sel[] = { | |
| 164 | + "lsp0_104M_wclk", | |
| 165 | + "lsp0_26M_wclk", | |
| 166 | +}; | |
| 167 | + | |
| 168 | +static const char * uart_wclk_sel[] = { | |
| 169 | + "lsp1_104M_wclk", | |
| 170 | + "lsp1_26M_wclk", | |
| 171 | +}; | |
| 172 | + | |
| 173 | +static inline struct clk *zx_divtbl(const char *name, const char *parent, | |
| 174 | + void __iomem *reg, u8 shift, u8 width, | |
| 175 | + const struct clk_div_table *table) | |
| 176 | +{ | |
| 177 | + return clk_register_divider_table(NULL, name, parent, 0, reg, shift, | |
| 178 | + width, 0, table, ®_lock); | |
| 179 | +} | |
| 180 | + | |
| 181 | +static inline struct clk *zx_div(const char *name, const char *parent, | |
| 182 | + void __iomem *reg, u8 shift, u8 width) | |
| 183 | +{ | |
| 184 | + return clk_register_divider(NULL, name, parent, 0, | |
| 185 | + reg, shift, width, 0, ®_lock); | |
| 186 | +} | |
| 187 | + | |
| 188 | +static inline struct clk *zx_mux(const char *name, const char **parents, | |
| 189 | + int num_parents, void __iomem *reg, u8 shift, u8 width) | |
| 190 | +{ | |
| 191 | + return clk_register_mux(NULL, name, parents, num_parents, | |
| 192 | + 0, reg, shift, width, 0, ®_lock); | |
| 193 | +} | |
| 194 | + | |
| 195 | +static inline struct clk *zx_gate(const char *name, const char *parent, | |
| 196 | + void __iomem *reg, u8 shift) | |
| 197 | +{ | |
| 198 | + return clk_register_gate(NULL, name, parent, CLK_IGNORE_UNUSED, | |
| 199 | + reg, shift, 0, ®_lock); | |
| 200 | +} | |
| 201 | + | |
| 202 | +static void __init zx296702_top_clocks_init(struct device_node *np) | |
| 203 | +{ | |
| 204 | + struct clk **clk = topclk; | |
| 205 | + int i; | |
| 206 | + | |
| 207 | + topcrm_base = of_iomap(np, 0); | |
| 208 | + WARN_ON(!topcrm_base); | |
| 209 | + | |
| 210 | + clk[ZX296702_OSC] = | |
| 211 | + clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, | |
| 212 | + 30000000); | |
| 213 | + clk[ZX296702_PLL_A9] = | |
| 214 | + clk_register_zx_pll("pll_a9", "osc", 0, topcrm_base | |
| 215 | + + 0x01c, pll_a9_config, | |
| 216 | + ARRAY_SIZE(pll_a9_config), ®_lock); | |
| 217 | + | |
| 218 | + /* TODO: pll_a9_350M look like changeble follow a9 pll */ | |
| 219 | + clk[ZX296702_PLL_A9_350M] = | |
| 220 | + clk_register_fixed_rate(NULL, "pll_a9_350M", "osc", 0, | |
| 221 | + 350000000); | |
| 222 | + clk[ZX296702_PLL_MAC_1000M] = | |
| 223 | + clk_register_fixed_rate(NULL, "pll_mac_1000M", "osc", 0, | |
| 224 | + 1000000000); | |
| 225 | + clk[ZX296702_PLL_MAC_333M] = | |
| 226 | + clk_register_fixed_rate(NULL, "pll_mac_333M", "osc", 0, | |
| 227 | + 333000000); | |
| 228 | + clk[ZX296702_PLL_MM0_1188M] = | |
| 229 | + clk_register_fixed_rate(NULL, "pll_mm0_1188M", "osc", 0, | |
| 230 | + 1188000000); | |
| 231 | + clk[ZX296702_PLL_MM0_396M] = | |
| 232 | + clk_register_fixed_rate(NULL, "pll_mm0_396M", "osc", 0, | |
| 233 | + 396000000); | |
| 234 | + clk[ZX296702_PLL_MM0_198M] = | |
| 235 | + clk_register_fixed_rate(NULL, "pll_mm0_198M", "osc", 0, | |
| 236 | + 198000000); | |
| 237 | + clk[ZX296702_PLL_MM1_108M] = | |
| 238 | + clk_register_fixed_rate(NULL, "pll_mm1_108M", "osc", 0, | |
| 239 | + 108000000); | |
| 240 | + clk[ZX296702_PLL_MM1_72M] = | |
| 241 | + clk_register_fixed_rate(NULL, "pll_mm1_72M", "osc", 0, | |
| 242 | + 72000000); | |
| 243 | + clk[ZX296702_PLL_MM1_54M] = | |
| 244 | + clk_register_fixed_rate(NULL, "pll_mm1_54M", "osc", 0, | |
| 245 | + 54000000); | |
| 246 | + clk[ZX296702_PLL_LSP_104M] = | |
| 247 | + clk_register_fixed_rate(NULL, "pll_lsp_104M", "osc", 0, | |
| 248 | + 104000000); | |
| 249 | + clk[ZX296702_PLL_LSP_26M] = | |
| 250 | + clk_register_fixed_rate(NULL, "pll_lsp_26M", "osc", 0, | |
| 251 | + 26000000); | |
| 252 | + clk[ZX296702_PLL_DDR_266M] = | |
| 253 | + clk_register_fixed_rate(NULL, "pll_ddr_266M", "osc", 0, | |
| 254 | + 266000000); | |
| 255 | + clk[ZX296702_PLL_AUDIO_294M912] = | |
| 256 | + clk_register_fixed_rate(NULL, "pll_audio_294M912", "osc", 0, | |
| 257 | + 294912000); | |
| 258 | + | |
| 259 | + /* bus clock */ | |
| 260 | + clk[ZX296702_MATRIX_ACLK] = | |
| 261 | + zx_mux("matrix_aclk", matrix_aclk_sel, | |
| 262 | + ARRAY_SIZE(matrix_aclk_sel), CLK_MUX, 2, 2); | |
| 263 | + clk[ZX296702_MAIN_HCLK] = | |
| 264 | + zx_divtbl("main_hclk", "matrix_aclk", CLK_DIV, 0, 2, | |
| 265 | + main_hlk_div); | |
| 266 | + clk[ZX296702_MAIN_PCLK] = | |
| 267 | + zx_divtbl("main_pclk", "matrix_aclk", CLK_DIV, 2, 2, | |
| 268 | + main_hlk_div); | |
| 269 | + | |
| 270 | + /* cpu clock */ | |
| 271 | + clk[ZX296702_CLK_500] = | |
| 272 | + clk_register_fixed_factor(NULL, "clk_500", "pll_mac_1000M", 0, | |
| 273 | + 1, 2); | |
| 274 | + clk[ZX296702_CLK_250] = | |
| 275 | + clk_register_fixed_factor(NULL, "clk_250", "pll_mac_1000M", 0, | |
| 276 | + 1, 4); | |
| 277 | + clk[ZX296702_CLK_125] = | |
| 278 | + clk_register_fixed_factor(NULL, "clk_125", "clk_250", 0, 1, 2); | |
| 279 | + clk[ZX296702_CLK_148M5] = | |
| 280 | + clk_register_fixed_factor(NULL, "clk_148M5", "pll_mm0_1188M", 0, | |
| 281 | + 1, 8); | |
| 282 | + clk[ZX296702_CLK_74M25] = | |
| 283 | + clk_register_fixed_factor(NULL, "clk_74M25", "pll_mm0_1188M", 0, | |
| 284 | + 1, 16); | |
| 285 | + clk[ZX296702_A9_WCLK] = | |
| 286 | + zx_mux("a9_wclk", a9_wclk_sel, ARRAY_SIZE(a9_wclk_sel), CLK_MUX, | |
| 287 | + 0, 2); | |
| 288 | + clk[ZX296702_A9_AS1_ACLK_MUX] = | |
| 289 | + zx_mux("a9_as1_aclk_mux", a9_as1_aclk_sel, | |
| 290 | + ARRAY_SIZE(a9_as1_aclk_sel), CLK_MUX, 4, 2); | |
| 291 | + clk[ZX296702_A9_TRACE_CLKIN_MUX] = | |
| 292 | + zx_mux("a9_trace_clkin_mux", a9_trace_clkin_sel, | |
| 293 | + ARRAY_SIZE(a9_trace_clkin_sel), CLK_MUX1, 0, 2); | |
| 294 | + clk[ZX296702_A9_AS1_ACLK_DIV] = | |
| 295 | + zx_divtbl("a9_as1_aclk_div", "a9_as1_aclk_mux", CLK_DIV, 4, 2, | |
| 296 | + a9_as1_aclk_divider); | |
| 297 | + | |
| 298 | + /* multi-media clock */ | |
| 299 | + clk[ZX296702_CLK_2] = | |
| 300 | + clk_register_fixed_factor(NULL, "clk_2", "pll_mm1_72M", 0, | |
| 301 | + 1, 36); | |
| 302 | + clk[ZX296702_CLK_27] = | |
| 303 | + clk_register_fixed_factor(NULL, "clk_27", "pll_mm1_54M", 0, | |
| 304 | + 1, 2); | |
| 305 | + clk[ZX296702_DECPPU_ACLK_MUX] = | |
| 306 | + zx_mux("decppu_aclk_mux", decppu_aclk_sel, | |
| 307 | + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 6, 2); | |
| 308 | + clk[ZX296702_PPU_ACLK_MUX] = | |
| 309 | + zx_mux("ppu_aclk_mux", decppu_aclk_sel, | |
| 310 | + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 8, 2); | |
| 311 | + clk[ZX296702_MALI400_ACLK_MUX] = | |
| 312 | + zx_mux("mali400_aclk_mux", decppu_aclk_sel, | |
| 313 | + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 12, 2); | |
| 314 | + clk[ZX296702_VOU_ACLK_MUX] = | |
| 315 | + zx_mux("vou_aclk_mux", decppu_aclk_sel, | |
| 316 | + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 10, 2); | |
| 317 | + clk[ZX296702_VOU_MAIN_WCLK_MUX] = | |
| 318 | + zx_mux("vou_main_wclk_mux", vou_main_wclk_sel, | |
| 319 | + ARRAY_SIZE(vou_main_wclk_sel), CLK_MUX, 14, 2); | |
| 320 | + clk[ZX296702_VOU_AUX_WCLK_MUX] = | |
| 321 | + zx_mux("vou_aux_wclk_mux", vou_main_wclk_sel, | |
| 322 | + ARRAY_SIZE(vou_main_wclk_sel), CLK_MUX, 16, 2); | |
| 323 | + clk[ZX296702_VOU_SCALER_WCLK_MUX] = | |
| 324 | + zx_mux("vou_scaler_wclk_mux", vou_scaler_wclk_sel, | |
| 325 | + ARRAY_SIZE(vou_scaler_wclk_sel), CLK_MUX, | |
| 326 | + 18, 2); | |
| 327 | + clk[ZX296702_R2D_ACLK_MUX] = | |
| 328 | + zx_mux("r2d_aclk_mux", decppu_aclk_sel, | |
| 329 | + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 20, 2); | |
| 330 | + clk[ZX296702_R2D_WCLK_MUX] = | |
| 331 | + zx_mux("r2d_wclk_mux", r2d_wclk_sel, | |
| 332 | + ARRAY_SIZE(r2d_wclk_sel), CLK_MUX, 22, 2); | |
| 333 | + | |
| 334 | + /* other clock */ | |
| 335 | + clk[ZX296702_CLK_50] = | |
| 336 | + clk_register_fixed_factor(NULL, "clk_50", "pll_mac_1000M", | |
| 337 | + 0, 1, 20); | |
| 338 | + clk[ZX296702_CLK_25] = | |
| 339 | + clk_register_fixed_factor(NULL, "clk_25", "pll_mac_1000M", | |
| 340 | + 0, 1, 40); | |
| 341 | + clk[ZX296702_CLK_12] = | |
| 342 | + clk_register_fixed_factor(NULL, "clk_12", "pll_mm1_72M", | |
| 343 | + 0, 1, 6); | |
| 344 | + clk[ZX296702_CLK_16M384] = | |
| 345 | + clk_register_fixed_factor(NULL, "clk_16M384", | |
| 346 | + "pll_audio_294M912", 0, 1, 18); | |
| 347 | + clk[ZX296702_CLK_32K768] = | |
| 348 | + clk_register_fixed_factor(NULL, "clk_32K768", "clk_16M384", | |
| 349 | + 0, 1, 500); | |
| 350 | + clk[ZX296702_SEC_WCLK_DIV] = | |
| 351 | + zx_divtbl("sec_wclk_div", "pll_lsp_104M", CLK_DIV, 6, 3, | |
| 352 | + sec_wclk_divider); | |
| 353 | + clk[ZX296702_DDR_WCLK_MUX] = | |
| 354 | + zx_mux("ddr_wclk_mux", ddr_wclk_sel, | |
| 355 | + ARRAY_SIZE(ddr_wclk_sel), CLK_MUX, 24, 2); | |
| 356 | + clk[ZX296702_NAND_WCLK_MUX] = | |
| 357 | + zx_mux("nand_wclk_mux", nand_wclk_sel, | |
| 358 | + ARRAY_SIZE(nand_wclk_sel), CLK_MUX, 24, 2); | |
| 359 | + clk[ZX296702_LSP_26_WCLK_MUX] = | |
| 360 | + zx_mux("lsp_26_wclk_mux", lsp_26_wclk_sel, | |
| 361 | + ARRAY_SIZE(lsp_26_wclk_sel), CLK_MUX, 27, 1); | |
| 362 | + | |
| 363 | + /* gates */ | |
| 364 | + clk[ZX296702_A9_AS0_ACLK] = | |
| 365 | + zx_gate("a9_as0_aclk", "matrix_aclk", CLK_EN0, 0); | |
| 366 | + clk[ZX296702_A9_AS1_ACLK] = | |
| 367 | + zx_gate("a9_as1_aclk", "a9_as1_aclk_div", CLK_EN0, 1); | |
| 368 | + clk[ZX296702_A9_TRACE_CLKIN] = | |
| 369 | + zx_gate("a9_trace_clkin", "a9_trace_clkin_mux", CLK_EN0, 2); | |
| 370 | + clk[ZX296702_DECPPU_AXI_M_ACLK] = | |
| 371 | + zx_gate("decppu_axi_m_aclk", "decppu_aclk_mux", CLK_EN0, 3); | |
| 372 | + clk[ZX296702_DECPPU_AHB_S_HCLK] = | |
| 373 | + zx_gate("decppu_ahb_s_hclk", "main_hclk", CLK_EN0, 4); | |
| 374 | + clk[ZX296702_PPU_AXI_M_ACLK] = | |
| 375 | + zx_gate("ppu_axi_m_aclk", "ppu_aclk_mux", CLK_EN0, 5); | |
| 376 | + clk[ZX296702_PPU_AHB_S_HCLK] = | |
| 377 | + zx_gate("ppu_ahb_s_hclk", "main_hclk", CLK_EN0, 6); | |
| 378 | + clk[ZX296702_VOU_AXI_M_ACLK] = | |
| 379 | + zx_gate("vou_axi_m_aclk", "vou_aclk_mux", CLK_EN0, 7); | |
| 380 | + clk[ZX296702_VOU_APB_PCLK] = | |
| 381 | + zx_gate("vou_apb_pclk", "main_pclk", CLK_EN0, 8); | |
| 382 | + clk[ZX296702_VOU_MAIN_CHANNEL_WCLK] = | |
| 383 | + zx_gate("vou_main_channel_wclk", "vou_main_wclk_mux", | |
| 384 | + CLK_EN0, 9); | |
| 385 | + clk[ZX296702_VOU_AUX_CHANNEL_WCLK] = | |
| 386 | + zx_gate("vou_aux_channel_wclk", "vou_aux_wclk_mux", | |
| 387 | + CLK_EN0, 10); | |
| 388 | + clk[ZX296702_VOU_HDMI_OSCLK_CEC] = | |
| 389 | + zx_gate("vou_hdmi_osclk_cec", "clk_2", CLK_EN0, 11); | |
| 390 | + clk[ZX296702_VOU_SCALER_WCLK] = | |
| 391 | + zx_gate("vou_scaler_wclk", "vou_scaler_wclk_mux", CLK_EN0, 12); | |
| 392 | + clk[ZX296702_MALI400_AXI_M_ACLK] = | |
| 393 | + zx_gate("mali400_axi_m_aclk", "mali400_aclk_mux", CLK_EN0, 13); | |
| 394 | + clk[ZX296702_MALI400_APB_PCLK] = | |
| 395 | + zx_gate("mali400_apb_pclk", "main_pclk", CLK_EN0, 14); | |
| 396 | + clk[ZX296702_R2D_WCLK] = | |
| 397 | + zx_gate("r2d_wclk", "r2d_wclk_mux", CLK_EN0, 15); | |
| 398 | + clk[ZX296702_R2D_AXI_M_ACLK] = | |
| 399 | + zx_gate("r2d_axi_m_aclk", "r2d_aclk_mux", CLK_EN0, 16); | |
| 400 | + clk[ZX296702_R2D_AHB_HCLK] = | |
| 401 | + zx_gate("r2d_ahb_hclk", "main_hclk", CLK_EN0, 17); | |
| 402 | + clk[ZX296702_DDR3_AXI_S0_ACLK] = | |
| 403 | + zx_gate("ddr3_axi_s0_aclk", "matrix_aclk", CLK_EN0, 18); | |
| 404 | + clk[ZX296702_DDR3_APB_PCLK] = | |
| 405 | + zx_gate("ddr3_apb_pclk", "main_pclk", CLK_EN0, 19); | |
| 406 | + clk[ZX296702_DDR3_WCLK] = | |
| 407 | + zx_gate("ddr3_wclk", "ddr_wclk_mux", CLK_EN0, 20); | |
| 408 | + clk[ZX296702_USB20_0_AHB_HCLK] = | |
| 409 | + zx_gate("usb20_0_ahb_hclk", "main_hclk", CLK_EN0, 21); | |
| 410 | + clk[ZX296702_USB20_0_EXTREFCLK] = | |
| 411 | + zx_gate("usb20_0_extrefclk", "clk_12", CLK_EN0, 22); | |
| 412 | + clk[ZX296702_USB20_1_AHB_HCLK] = | |
| 413 | + zx_gate("usb20_1_ahb_hclk", "main_hclk", CLK_EN0, 23); | |
| 414 | + clk[ZX296702_USB20_1_EXTREFCLK] = | |
| 415 | + zx_gate("usb20_1_extrefclk", "clk_12", CLK_EN0, 24); | |
| 416 | + clk[ZX296702_USB20_2_AHB_HCLK] = | |
| 417 | + zx_gate("usb20_2_ahb_hclk", "main_hclk", CLK_EN0, 25); | |
| 418 | + clk[ZX296702_USB20_2_EXTREFCLK] = | |
| 419 | + zx_gate("usb20_2_extrefclk", "clk_12", CLK_EN0, 26); | |
| 420 | + clk[ZX296702_GMAC_AXI_M_ACLK] = | |
| 421 | + zx_gate("gmac_axi_m_aclk", "matrix_aclk", CLK_EN0, 27); | |
| 422 | + clk[ZX296702_GMAC_APB_PCLK] = | |
| 423 | + zx_gate("gmac_apb_pclk", "main_pclk", CLK_EN0, 28); | |
| 424 | + clk[ZX296702_GMAC_125_CLKIN] = | |
| 425 | + zx_gate("gmac_125_clkin", "clk_125", CLK_EN0, 29); | |
| 426 | + clk[ZX296702_GMAC_RMII_CLKIN] = | |
| 427 | + zx_gate("gmac_rmii_clkin", "clk_50", CLK_EN0, 30); | |
| 428 | + clk[ZX296702_GMAC_25M_CLK] = | |
| 429 | + zx_gate("gmac_25M_clk", "clk_25", CLK_EN0, 31); | |
| 430 | + clk[ZX296702_NANDFLASH_AHB_HCLK] = | |
| 431 | + zx_gate("nandflash_ahb_hclk", "main_hclk", CLK_EN1, 0); | |
| 432 | + clk[ZX296702_NANDFLASH_WCLK] = | |
| 433 | + zx_gate("nandflash_wclk", "nand_wclk_mux", CLK_EN1, 1); | |
| 434 | + clk[ZX296702_LSP0_APB_PCLK] = | |
| 435 | + zx_gate("lsp0_apb_pclk", "main_pclk", CLK_EN1, 2); | |
| 436 | + clk[ZX296702_LSP0_AHB_HCLK] = | |
| 437 | + zx_gate("lsp0_ahb_hclk", "main_hclk", CLK_EN1, 3); | |
| 438 | + clk[ZX296702_LSP0_26M_WCLK] = | |
| 439 | + zx_gate("lsp0_26M_wclk", "lsp_26_wclk_mux", CLK_EN1, 4); | |
| 440 | + clk[ZX296702_LSP0_104M_WCLK] = | |
| 441 | + zx_gate("lsp0_104M_wclk", "pll_lsp_104M", CLK_EN1, 5); | |
| 442 | + clk[ZX296702_LSP0_16M384_WCLK] = | |
| 443 | + zx_gate("lsp0_16M384_wclk", "clk_16M384", CLK_EN1, 6); | |
| 444 | + clk[ZX296702_LSP1_APB_PCLK] = | |
| 445 | + zx_gate("lsp1_apb_pclk", "main_pclk", CLK_EN1, 7); | |
| 446 | + /* FIXME: wclk enable bit is bit8. We hack it as reserved 31 for | |
| 447 | + * UART does not work after parent clk is disabled/enabled */ | |
| 448 | + clk[ZX296702_LSP1_26M_WCLK] = | |
| 449 | + zx_gate("lsp1_26M_wclk", "lsp_26_wclk_mux", CLK_EN1, 31); | |
| 450 | + clk[ZX296702_LSP1_104M_WCLK] = | |
| 451 | + zx_gate("lsp1_104M_wclk", "pll_lsp_104M", CLK_EN1, 9); | |
| 452 | + clk[ZX296702_LSP1_32K_CLK] = | |
| 453 | + zx_gate("lsp1_32K_clk", "clk_32K768", CLK_EN1, 10); | |
| 454 | + clk[ZX296702_AON_HCLK] = | |
| 455 | + zx_gate("aon_hclk", "main_hclk", CLK_EN1, 11); | |
| 456 | + clk[ZX296702_SYS_CTRL_PCLK] = | |
| 457 | + zx_gate("sys_ctrl_pclk", "main_pclk", CLK_EN1, 12); | |
| 458 | + clk[ZX296702_DMA_PCLK] = | |
| 459 | + zx_gate("dma_pclk", "main_pclk", CLK_EN1, 13); | |
| 460 | + clk[ZX296702_DMA_ACLK] = | |
| 461 | + zx_gate("dma_aclk", "matrix_aclk", CLK_EN1, 14); | |
| 462 | + clk[ZX296702_SEC_HCLK] = | |
| 463 | + zx_gate("sec_hclk", "main_hclk", CLK_EN1, 15); | |
| 464 | + clk[ZX296702_AES_WCLK] = | |
| 465 | + zx_gate("aes_wclk", "sec_wclk_div", CLK_EN1, 16); | |
| 466 | + clk[ZX296702_DES_WCLK] = | |
| 467 | + zx_gate("des_wclk", "sec_wclk_div", CLK_EN1, 17); | |
| 468 | + clk[ZX296702_IRAM_ACLK] = | |
| 469 | + zx_gate("iram_aclk", "matrix_aclk", CLK_EN1, 18); | |
| 470 | + clk[ZX296702_IROM_ACLK] = | |
| 471 | + zx_gate("irom_aclk", "matrix_aclk", CLK_EN1, 19); | |
| 472 | + clk[ZX296702_BOOT_CTRL_HCLK] = | |
| 473 | + zx_gate("boot_ctrl_hclk", "main_hclk", CLK_EN1, 20); | |
| 474 | + clk[ZX296702_EFUSE_CLK_30] = | |
| 475 | + zx_gate("efuse_clk_30", "osc", CLK_EN1, 21); | |
| 476 | + | |
| 477 | + /* TODO: add VOU Local clocks */ | |
| 478 | + clk[ZX296702_VOU_MAIN_CHANNEL_DIV] = | |
| 479 | + zx_div("vou_main_channel_div", "vou_main_channel_wclk", | |
| 480 | + VOU_LOCAL_DIV2_SET, 1, 1); | |
| 481 | + clk[ZX296702_VOU_AUX_CHANNEL_DIV] = | |
| 482 | + zx_div("vou_aux_channel_div", "vou_aux_channel_wclk", | |
| 483 | + VOU_LOCAL_DIV2_SET, 0, 1); | |
| 484 | + clk[ZX296702_VOU_TV_ENC_HD_DIV] = | |
| 485 | + zx_div("vou_tv_enc_hd_div", "vou_tv_enc_hd_mux", | |
| 486 | + VOU_LOCAL_DIV2_SET, 3, 1); | |
| 487 | + clk[ZX296702_VOU_TV_ENC_SD_DIV] = | |
| 488 | + zx_div("vou_tv_enc_sd_div", "vou_tv_enc_sd_mux", | |
| 489 | + VOU_LOCAL_DIV2_SET, 2, 1); | |
| 490 | + clk[ZX296702_VL0_MUX] = | |
| 491 | + zx_mux("vl0_mux", vl0_sel, ARRAY_SIZE(vl0_sel), | |
| 492 | + VOU_LOCAL_CLKSEL, 8, 1); | |
| 493 | + clk[ZX296702_VL1_MUX] = | |
| 494 | + zx_mux("vl1_mux", vl0_sel, ARRAY_SIZE(vl0_sel), | |
| 495 | + VOU_LOCAL_CLKSEL, 9, 1); | |
| 496 | + clk[ZX296702_VL2_MUX] = | |
| 497 | + zx_mux("vl2_mux", vl0_sel, ARRAY_SIZE(vl0_sel), | |
| 498 | + VOU_LOCAL_CLKSEL, 10, 1); | |
| 499 | + clk[ZX296702_GL0_MUX] = | |
| 500 | + zx_mux("gl0_mux", vl0_sel, ARRAY_SIZE(vl0_sel), | |
| 501 | + VOU_LOCAL_CLKSEL, 5, 1); | |
| 502 | + clk[ZX296702_GL1_MUX] = | |
| 503 | + zx_mux("gl1_mux", vl0_sel, ARRAY_SIZE(vl0_sel), | |
| 504 | + VOU_LOCAL_CLKSEL, 6, 1); | |
| 505 | + clk[ZX296702_GL2_MUX] = | |
| 506 | + zx_mux("gl2_mux", vl0_sel, ARRAY_SIZE(vl0_sel), | |
| 507 | + VOU_LOCAL_CLKSEL, 7, 1); | |
| 508 | + clk[ZX296702_WB_MUX] = | |
| 509 | + zx_mux("wb_mux", vl0_sel, ARRAY_SIZE(vl0_sel), | |
| 510 | + VOU_LOCAL_CLKSEL, 11, 1); | |
| 511 | + clk[ZX296702_HDMI_MUX] = | |
| 512 | + zx_mux("hdmi_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel), | |
| 513 | + VOU_LOCAL_CLKSEL, 4, 1); | |
| 514 | + clk[ZX296702_VOU_TV_ENC_HD_MUX] = | |
| 515 | + zx_mux("vou_tv_enc_hd_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel), | |
| 516 | + VOU_LOCAL_CLKSEL, 3, 1); | |
| 517 | + clk[ZX296702_VOU_TV_ENC_SD_MUX] = | |
| 518 | + zx_mux("vou_tv_enc_sd_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel), | |
| 519 | + VOU_LOCAL_CLKSEL, 2, 1); | |
| 520 | + clk[ZX296702_VL0_CLK] = | |
| 521 | + zx_gate("vl0_clk", "vl0_mux", VOU_LOCAL_CLKEN, 8); | |
| 522 | + clk[ZX296702_VL1_CLK] = | |
| 523 | + zx_gate("vl1_clk", "vl1_mux", VOU_LOCAL_CLKEN, 9); | |
| 524 | + clk[ZX296702_VL2_CLK] = | |
| 525 | + zx_gate("vl2_clk", "vl2_mux", VOU_LOCAL_CLKEN, 10); | |
| 526 | + clk[ZX296702_GL0_CLK] = | |
| 527 | + zx_gate("gl0_clk", "gl0_mux", VOU_LOCAL_CLKEN, 5); | |
| 528 | + clk[ZX296702_GL1_CLK] = | |
| 529 | + zx_gate("gl1_clk", "gl1_mux", VOU_LOCAL_CLKEN, 6); | |
| 530 | + clk[ZX296702_GL2_CLK] = | |
| 531 | + zx_gate("gl2_clk", "gl2_mux", VOU_LOCAL_CLKEN, 7); | |
| 532 | + clk[ZX296702_WB_CLK] = | |
| 533 | + zx_gate("wb_clk", "wb_mux", VOU_LOCAL_CLKEN, 11); | |
| 534 | + clk[ZX296702_CL_CLK] = | |
| 535 | + zx_gate("cl_clk", "vou_main_channel_div", VOU_LOCAL_CLKEN, 12); | |
| 536 | + clk[ZX296702_MAIN_MIX_CLK] = | |
| 537 | + zx_gate("main_mix_clk", "vou_main_channel_div", | |
| 538 | + VOU_LOCAL_CLKEN, 4); | |
| 539 | + clk[ZX296702_AUX_MIX_CLK] = | |
| 540 | + zx_gate("aux_mix_clk", "vou_aux_channel_div", | |
| 541 | + VOU_LOCAL_CLKEN, 3); | |
| 542 | + clk[ZX296702_HDMI_CLK] = | |
| 543 | + zx_gate("hdmi_clk", "hdmi_mux", VOU_LOCAL_CLKEN, 2); | |
| 544 | + clk[ZX296702_VOU_TV_ENC_HD_DAC_CLK] = | |
| 545 | + zx_gate("vou_tv_enc_hd_dac_clk", "vou_tv_enc_hd_div", | |
| 546 | + VOU_LOCAL_CLKEN, 1); | |
| 547 | + clk[ZX296702_VOU_TV_ENC_SD_DAC_CLK] = | |
| 548 | + zx_gate("vou_tv_enc_sd_dac_clk", "vou_tv_enc_sd_div", | |
| 549 | + VOU_LOCAL_CLKEN, 0); | |
| 550 | + | |
| 551 | + /* CA9 PERIPHCLK = a9_wclk / 2 */ | |
| 552 | + clk[ZX296702_A9_PERIPHCLK] = | |
| 553 | + clk_register_fixed_factor(NULL, "a9_periphclk", "a9_wclk", | |
| 554 | + 0, 1, 2); | |
| 555 | + | |
| 556 | + for (i = 0; i < ARRAY_SIZE(topclk); i++) { | |
| 557 | + if (IS_ERR(clk[i])) { | |
| 558 | + pr_err("zx296702 clk %d: register failed with %ld\n", | |
| 559 | + i, PTR_ERR(clk[i])); | |
| 560 | + return; | |
| 561 | + } | |
| 562 | + } | |
| 563 | + | |
| 564 | + topclk_data.clks = topclk; | |
| 565 | + topclk_data.clk_num = ARRAY_SIZE(topclk); | |
| 566 | + of_clk_add_provider(np, of_clk_src_onecell_get, &topclk_data); | |
| 567 | +} | |
| 568 | +CLK_OF_DECLARE(zx296702_top_clk, "zte,zx296702-topcrm-clk", | |
| 569 | + zx296702_top_clocks_init); | |
| 570 | + | |
| 571 | +static void __init zx296702_lsp0_clocks_init(struct device_node *np) | |
| 572 | +{ | |
| 573 | + struct clk **clk = lsp0clk; | |
| 574 | + int i; | |
| 575 | + | |
| 576 | + lsp0crpm_base = of_iomap(np, 0); | |
| 577 | + WARN_ON(!lsp0crpm_base); | |
| 578 | + | |
| 579 | + /* SDMMC1 */ | |
| 580 | + clk[ZX296702_SDMMC1_WCLK_MUX] = | |
| 581 | + zx_mux("sdmmc1_wclk_mux", sdmmc1_wclk_sel, | |
| 582 | + ARRAY_SIZE(sdmmc1_wclk_sel), CLK_SDMMC1, 4, 1); | |
| 583 | + clk[ZX296702_SDMMC1_WCLK_DIV] = | |
| 584 | + zx_div("sdmmc1_wclk_div", "sdmmc1_wclk_mux", CLK_SDMMC1, 12, 4); | |
| 585 | + clk[ZX296702_SDMMC1_WCLK] = | |
| 586 | + zx_gate("sdmmc1_wclk", "sdmmc1_wclk_div", CLK_SDMMC1, 1); | |
| 587 | + clk[ZX296702_SDMMC1_PCLK] = | |
| 588 | + zx_gate("sdmmc1_pclk", "lsp1_apb_pclk", CLK_SDMMC1, 0); | |
| 589 | + | |
| 590 | + for (i = 0; i < ARRAY_SIZE(lsp0clk); i++) { | |
| 591 | + if (IS_ERR(clk[i])) { | |
| 592 | + pr_err("zx296702 clk %d: register failed with %ld\n", | |
| 593 | + i, PTR_ERR(clk[i])); | |
| 594 | + return; | |
| 595 | + } | |
| 596 | + } | |
| 597 | + | |
| 598 | + lsp0clk_data.clks = lsp0clk; | |
| 599 | + lsp0clk_data.clk_num = ARRAY_SIZE(lsp0clk); | |
| 600 | + of_clk_add_provider(np, of_clk_src_onecell_get, &lsp0clk_data); | |
| 601 | +} | |
| 602 | +CLK_OF_DECLARE(zx296702_lsp0_clk, "zte,zx296702-lsp0crpm-clk", | |
| 603 | + zx296702_lsp0_clocks_init); | |
| 604 | + | |
| 605 | +static void __init zx296702_lsp1_clocks_init(struct device_node *np) | |
| 606 | +{ | |
| 607 | + struct clk **clk = lsp1clk; | |
| 608 | + int i; | |
| 609 | + | |
| 610 | + lsp1crpm_base = of_iomap(np, 0); | |
| 611 | + WARN_ON(!lsp1crpm_base); | |
| 612 | + | |
| 613 | + /* UART0 */ | |
| 614 | + clk[ZX296702_UART0_WCLK_MUX] = | |
| 615 | + zx_mux("uart0_wclk_mux", uart_wclk_sel, | |
| 616 | + ARRAY_SIZE(uart_wclk_sel), CLK_UART0, 4, 1); | |
| 617 | + /* FIXME: uart wclk enable bit is bit1 in. We hack it as reserved 31 for | |
| 618 | + * UART does not work after parent clk is disabled/enabled */ | |
| 619 | + clk[ZX296702_UART0_WCLK] = | |
| 620 | + zx_gate("uart0_wclk", "uart0_wclk_mux", CLK_UART0, 31); | |
| 621 | + clk[ZX296702_UART0_PCLK] = | |
| 622 | + zx_gate("uart0_pclk", "lsp1_apb_pclk", CLK_UART0, 0); | |
| 623 | + | |
| 624 | + /* UART1 */ | |
| 625 | + clk[ZX296702_UART1_WCLK_MUX] = | |
| 626 | + zx_mux("uart1_wclk_mux", uart_wclk_sel, | |
| 627 | + ARRAY_SIZE(uart_wclk_sel), CLK_UART1, 4, 1); | |
| 628 | + clk[ZX296702_UART1_WCLK] = | |
| 629 | + zx_gate("uart1_wclk", "uart1_wclk_mux", CLK_UART1, 1); | |
| 630 | + clk[ZX296702_UART1_PCLK] = | |
| 631 | + zx_gate("uart1_pclk", "lsp1_apb_pclk", CLK_UART1, 0); | |
| 632 | + | |
| 633 | + /* SDMMC0 */ | |
| 634 | + clk[ZX296702_SDMMC0_WCLK_MUX] = | |
| 635 | + zx_mux("sdmmc0_wclk_mux", sdmmc0_wclk_sel, | |
| 636 | + ARRAY_SIZE(sdmmc0_wclk_sel), CLK_SDMMC0, 4, 1); | |
| 637 | + clk[ZX296702_SDMMC0_WCLK_DIV] = | |
| 638 | + zx_div("sdmmc0_wclk_div", "sdmmc0_wclk_mux", CLK_SDMMC0, 12, 4); | |
| 639 | + clk[ZX296702_SDMMC0_WCLK] = | |
| 640 | + zx_gate("sdmmc0_wclk", "sdmmc0_wclk_div", CLK_SDMMC0, 1); | |
| 641 | + clk[ZX296702_SDMMC0_PCLK] = | |
| 642 | + zx_gate("sdmmc0_pclk", "lsp1_apb_pclk", CLK_SDMMC0, 0); | |
| 643 | + | |
| 644 | + for (i = 0; i < ARRAY_SIZE(lsp1clk); i++) { | |
| 645 | + if (IS_ERR(clk[i])) { | |
| 646 | + pr_err("zx296702 clk %d: register failed with %ld\n", | |
| 647 | + i, PTR_ERR(clk[i])); | |
| 648 | + return; | |
| 649 | + } | |
| 650 | + } | |
| 651 | + | |
| 652 | + lsp1clk_data.clks = lsp1clk; | |
| 653 | + lsp1clk_data.clk_num = ARRAY_SIZE(lsp1clk); | |
| 654 | + of_clk_add_provider(np, of_clk_src_onecell_get, &lsp1clk_data); | |
| 655 | +} | |
| 656 | +CLK_OF_DECLARE(zx296702_lsp1_clk, "zte,zx296702-lsp1crpm-clk", | |
| 657 | + zx296702_lsp1_clocks_init); | |
| @@ -0,0 +1,32 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2015 Linaro Ltd. | |
| 3 | + * Copyright (C) 2014 ZTE Corporation. | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#ifndef __ZTE_CLK_H | |
| 11 | +#define __ZTE_CLK_H | |
| 12 | +#include <linux/clk-provider.h> | |
| 13 | +#include <linux/spinlock.h> | |
| 14 | + | |
| 15 | +struct zx_pll_config { | |
| 16 | + unsigned long rate; | |
| 17 | + u32 cfg0; | |
| 18 | + u32 cfg1; | |
| 19 | +}; | |
| 20 | + | |
| 21 | +struct clk_zx_pll { | |
| 22 | + struct clk_hw hw; | |
| 23 | + void __iomem *reg_base; | |
| 24 | + const struct zx_pll_config *lookup_table; /* order by rate asc */ | |
| 25 | + int count; | |
| 26 | + spinlock_t *lock; | |
| 27 | +}; | |
| 28 | + | |
| 29 | +struct clk *clk_register_zx_pll(const char *name, const char *parent_name, | |
| 30 | + unsigned long flags, void __iomem *reg_base, | |
| 31 | + const struct zx_pll_config *lookup_table, int count, spinlock_t *lock); | |
| 32 | +#endif | |
| @@ -282,4 +282,9 @@ config H8300_TMR16 · 281 unmodified lines | ||
| 282 | 282 | config H8300_TPU |
| 283 | 283 | bool |
| 284 | 284 | |
| 285 | +config CLKSRC_IMX_GPT | |
| 286 | + bool "Clocksource using i.MX GPT" if COMPILE_TEST | |
| 287 | + depends on ARM && CLKDEV_LOOKUP | |
| 288 | + select CLKSRC_MMIO | |
| 289 | + | |
| 285 | 290 | endmenu |
| @@ -54,6 +54,7 @@ obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o · 53 unmodified lines | ||
| 54 | 54 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o |
| 55 | 55 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o |
| 56 | 56 | obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o |
| 57 | +obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o | |
| 57 | 58 | obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o |
| 58 | 59 | obj-$(CONFIG_H8300) += h8300_timer8.o |
| 59 | 60 | obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o |
| @@ -0,0 +1,540 @@ | ||
| 1 | +/* | |
| 2 | + * linux/arch/arm/plat-mxc/time.c | |
| 3 | + * | |
| 4 | + * Copyright (C) 2000-2001 Deep Blue Solutions | |
| 5 | + * Copyright (C) 2002 Shane Nay (shane@minirl.com) | |
| 6 | + * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) | |
| 7 | + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) | |
| 8 | + * | |
| 9 | + * This program is free software; you can redistribute it and/or | |
| 10 | + * modify it under the terms of the GNU General Public License | |
| 11 | + * as published by the Free Software Foundation; either version 2 | |
| 12 | + * of the License, or (at your option) any later version. | |
| 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 | + * You should have received a copy of the GNU General Public License | |
| 19 | + * along with this program; if not, write to the Free Software | |
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 21 | + * MA 02110-1301, USA. | |
| 22 | + */ | |
| 23 | + | |
| 24 | +#include <linux/interrupt.h> | |
| 25 | +#include <linux/irq.h> | |
| 26 | +#include <linux/clockchips.h> | |
| 27 | +#include <linux/clk.h> | |
| 28 | +#include <linux/delay.h> | |
| 29 | +#include <linux/err.h> | |
| 30 | +#include <linux/sched_clock.h> | |
| 31 | +#include <linux/slab.h> | |
| 32 | +#include <linux/of.h> | |
| 33 | +#include <linux/of_address.h> | |
| 34 | +#include <linux/of_irq.h> | |
| 35 | +#include <soc/imx/timer.h> | |
| 36 | + | |
| 37 | +/* | |
| 38 | + * There are 4 versions of the timer hardware on Freescale MXC hardware. | |
| 39 | + * - MX1/MXL | |
| 40 | + * - MX21, MX27. | |
| 41 | + * - MX25, MX31, MX35, MX37, MX51, MX6Q(rev1.0) | |
| 42 | + * - MX6DL, MX6SX, MX6Q(rev1.1+) | |
| 43 | + */ | |
| 44 | + | |
| 45 | +/* defines common for all i.MX */ | |
| 46 | +#define MXC_TCTL 0x00 | |
| 47 | +#define MXC_TCTL_TEN (1 << 0) /* Enable module */ | |
| 48 | +#define MXC_TPRER 0x04 | |
| 49 | + | |
| 50 | +/* MX1, MX21, MX27 */ | |
| 51 | +#define MX1_2_TCTL_CLK_PCLK1 (1 << 1) | |
| 52 | +#define MX1_2_TCTL_IRQEN (1 << 4) | |
| 53 | +#define MX1_2_TCTL_FRR (1 << 8) | |
| 54 | +#define MX1_2_TCMP 0x08 | |
| 55 | +#define MX1_2_TCN 0x10 | |
| 56 | +#define MX1_2_TSTAT 0x14 | |
| 57 | + | |
| 58 | +/* MX21, MX27 */ | |
| 59 | +#define MX2_TSTAT_CAPT (1 << 1) | |
| 60 | +#define MX2_TSTAT_COMP (1 << 0) | |
| 61 | + | |
| 62 | +/* MX31, MX35, MX25, MX5, MX6 */ | |
| 63 | +#define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ | |
| 64 | +#define V2_TCTL_CLK_IPG (1 << 6) | |
| 65 | +#define V2_TCTL_CLK_PER (2 << 6) | |
| 66 | +#define V2_TCTL_CLK_OSC_DIV8 (5 << 6) | |
| 67 | +#define V2_TCTL_FRR (1 << 9) | |
| 68 | +#define V2_TCTL_24MEN (1 << 10) | |
| 69 | +#define V2_TPRER_PRE24M 12 | |
| 70 | +#define V2_IR 0x0c | |
| 71 | +#define V2_TSTAT 0x08 | |
| 72 | +#define V2_TSTAT_OF1 (1 << 0) | |
| 73 | +#define V2_TCN 0x24 | |
| 74 | +#define V2_TCMP 0x10 | |
| 75 | + | |
| 76 | +#define V2_TIMER_RATE_OSC_DIV8 3000000 | |
| 77 | + | |
| 78 | +struct imx_timer { | |
| 79 | + enum imx_gpt_type type; | |
| 80 | + void __iomem *base; | |
| 81 | + int irq; | |
| 82 | + struct clk *clk_per; | |
| 83 | + struct clk *clk_ipg; | |
| 84 | + const struct imx_gpt_data *gpt; | |
| 85 | + struct clock_event_device ced; | |
| 86 | + enum clock_event_mode cem; | |
| 87 | + struct irqaction act; | |
| 88 | +}; | |
| 89 | + | |
| 90 | +struct imx_gpt_data { | |
| 91 | + int reg_tstat; | |
| 92 | + int reg_tcn; | |
| 93 | + int reg_tcmp; | |
| 94 | + void (*gpt_setup_tctl)(struct imx_timer *imxtm); | |
| 95 | + void (*gpt_irq_enable)(struct imx_timer *imxtm); | |
| 96 | + void (*gpt_irq_disable)(struct imx_timer *imxtm); | |
| 97 | + void (*gpt_irq_acknowledge)(struct imx_timer *imxtm); | |
| 98 | + int (*set_next_event)(unsigned long evt, | |
| 99 | + struct clock_event_device *ced); | |
| 100 | +}; | |
| 101 | + | |
| 102 | +static inline struct imx_timer *to_imx_timer(struct clock_event_device *ced) | |
| 103 | +{ | |
| 104 | + return container_of(ced, struct imx_timer, ced); | |
| 105 | +} | |
| 106 | + | |
| 107 | +static void imx1_gpt_irq_disable(struct imx_timer *imxtm) | |
| 108 | +{ | |
| 109 | + unsigned int tmp; | |
| 110 | + | |
| 111 | + tmp = readl_relaxed(imxtm->base + MXC_TCTL); | |
| 112 | + writel_relaxed(tmp & ~MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL); | |
| 113 | +} | |
| 114 | +#define imx21_gpt_irq_disable imx1_gpt_irq_disable | |
| 115 | + | |
| 116 | +static void imx31_gpt_irq_disable(struct imx_timer *imxtm) | |
| 117 | +{ | |
| 118 | + writel_relaxed(0, imxtm->base + V2_IR); | |
| 119 | +} | |
| 120 | +#define imx6dl_gpt_irq_disable imx31_gpt_irq_disable | |
| 121 | + | |
| 122 | +static void imx1_gpt_irq_enable(struct imx_timer *imxtm) | |
| 123 | +{ | |
| 124 | + unsigned int tmp; | |
| 125 | + | |
| 126 | + tmp = readl_relaxed(imxtm->base + MXC_TCTL); | |
| 127 | + writel_relaxed(tmp | MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL); | |
| 128 | +} | |
| 129 | +#define imx21_gpt_irq_enable imx1_gpt_irq_enable | |
| 130 | + | |
| 131 | +static void imx31_gpt_irq_enable(struct imx_timer *imxtm) | |
| 132 | +{ | |
| 133 | + writel_relaxed(1<<0, imxtm->base + V2_IR); | |
| 134 | +} | |
| 135 | +#define imx6dl_gpt_irq_enable imx31_gpt_irq_enable | |
| 136 | + | |
| 137 | +static void imx1_gpt_irq_acknowledge(struct imx_timer *imxtm) | |
| 138 | +{ | |
| 139 | + writel_relaxed(0, imxtm->base + MX1_2_TSTAT); | |
| 140 | +} | |
| 141 | + | |
| 142 | +static void imx21_gpt_irq_acknowledge(struct imx_timer *imxtm) | |
| 143 | +{ | |
| 144 | + writel_relaxed(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, | |
| 145 | + imxtm->base + MX1_2_TSTAT); | |
| 146 | +} | |
| 147 | + | |
| 148 | +static void imx31_gpt_irq_acknowledge(struct imx_timer *imxtm) | |
| 149 | +{ | |
| 150 | + writel_relaxed(V2_TSTAT_OF1, imxtm->base + V2_TSTAT); | |
| 151 | +} | |
| 152 | +#define imx6dl_gpt_irq_acknowledge imx31_gpt_irq_acknowledge | |
| 153 | + | |
| 154 | +static void __iomem *sched_clock_reg; | |
| 155 | + | |
| 156 | +static u64 notrace mxc_read_sched_clock(void) | |
| 157 | +{ | |
| 158 | + return sched_clock_reg ? readl_relaxed(sched_clock_reg) : 0; | |
| 159 | +} | |
| 160 | + | |
| 161 | +static struct delay_timer imx_delay_timer; | |
| 162 | + | |
| 163 | +static unsigned long imx_read_current_timer(void) | |
| 164 | +{ | |
| 165 | + return readl_relaxed(sched_clock_reg); | |
| 166 | +} | |
| 167 | + | |
| 168 | +static int __init mxc_clocksource_init(struct imx_timer *imxtm) | |
| 169 | +{ | |
| 170 | + unsigned int c = clk_get_rate(imxtm->clk_per); | |
| 171 | + void __iomem *reg = imxtm->base + imxtm->gpt->reg_tcn; | |
| 172 | + | |
| 173 | + imx_delay_timer.read_current_timer = &imx_read_current_timer; | |
| 174 | + imx_delay_timer.freq = c; | |
| 175 | + register_current_timer_delay(&imx_delay_timer); | |
| 176 | + | |
| 177 | + sched_clock_reg = reg; | |
| 178 | + | |
| 179 | + sched_clock_register(mxc_read_sched_clock, 32, c); | |
| 180 | + return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, | |
| 181 | + clocksource_mmio_readl_up); | |
| 182 | +} | |
| 183 | + | |
| 184 | +/* clock event */ | |
| 185 | + | |
| 186 | +static int mx1_2_set_next_event(unsigned long evt, | |
| 187 | + struct clock_event_device *ced) | |
| 188 | +{ | |
| 189 | + struct imx_timer *imxtm = to_imx_timer(ced); | |
| 190 | + unsigned long tcmp; | |
| 191 | + | |
| 192 | + tcmp = readl_relaxed(imxtm->base + MX1_2_TCN) + evt; | |
| 193 | + | |
| 194 | + writel_relaxed(tcmp, imxtm->base + MX1_2_TCMP); | |
| 195 | + | |
| 196 | + return (int)(tcmp - readl_relaxed(imxtm->base + MX1_2_TCN)) < 0 ? | |
| 197 | + -ETIME : 0; | |
| 198 | +} | |
| 199 | + | |
| 200 | +static int v2_set_next_event(unsigned long evt, | |
| 201 | + struct clock_event_device *ced) | |
| 202 | +{ | |
| 203 | + struct imx_timer *imxtm = to_imx_timer(ced); | |
| 204 | + unsigned long tcmp; | |
| 205 | + | |
| 206 | + tcmp = readl_relaxed(imxtm->base + V2_TCN) + evt; | |
| 207 | + | |
| 208 | + writel_relaxed(tcmp, imxtm->base + V2_TCMP); | |
| 209 | + | |
| 210 | + return evt < 0x7fffffff && | |
| 211 | + (int)(tcmp - readl_relaxed(imxtm->base + V2_TCN)) < 0 ? | |
| 212 | + -ETIME : 0; | |
| 213 | +} | |
| 214 | + | |
| 215 | +#ifdef DEBUG | |
| 216 | +static const char *clock_event_mode_label[] = { | |
| 217 | + [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC", | |
| 218 | + [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT", | |
| 219 | + [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN", | |
| 220 | + [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED", | |
| 221 | + [CLOCK_EVT_MODE_RESUME] = "CLOCK_EVT_MODE_RESUME", | |
| 222 | +}; | |
| 223 | +#endif /* DEBUG */ | |
| 224 | + | |
| 225 | +static void mxc_set_mode(enum clock_event_mode mode, | |
| 226 | + struct clock_event_device *ced) | |
| 227 | +{ | |
| 228 | + struct imx_timer *imxtm = to_imx_timer(ced); | |
| 229 | + unsigned long flags; | |
| 230 | + | |
| 231 | + /* | |
| 232 | + * The timer interrupt generation is disabled at least | |
| 233 | + * for enough time to call mxc_set_next_event() | |
| 234 | + */ | |
| 235 | + local_irq_save(flags); | |
| 236 | + | |
| 237 | + /* Disable interrupt in GPT module */ | |
| 238 | + imxtm->gpt->gpt_irq_disable(imxtm); | |
| 239 | + | |
| 240 | + if (mode != imxtm->cem) { | |
| 241 | + u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn); | |
| 242 | + /* Set event time into far-far future */ | |
| 243 | + writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp); | |
| 244 | + | |
| 245 | + /* Clear pending interrupt */ | |
| 246 | + imxtm->gpt->gpt_irq_acknowledge(imxtm); | |
| 247 | + } | |
| 248 | + | |
| 249 | +#ifdef DEBUG | |
| 250 | + printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n", | |
| 251 | + clock_event_mode_label[imxtm->cem], | |
| 252 | + clock_event_mode_label[mode]); | |
| 253 | +#endif /* DEBUG */ | |
| 254 | + | |
| 255 | + /* Remember timer mode */ | |
| 256 | + imxtm->cem = mode; | |
| 257 | + local_irq_restore(flags); | |
| 258 | + | |
| 259 | + switch (mode) { | |
| 260 | + case CLOCK_EVT_MODE_PERIODIC: | |
| 261 | + printk(KERN_ERR"mxc_set_mode: Periodic mode is not " | |
| 262 | + "supported for i.MX\n"); | |
| 263 | + break; | |
| 264 | + case CLOCK_EVT_MODE_ONESHOT: | |
| 265 | + /* | |
| 266 | + * Do not put overhead of interrupt enable/disable into | |
| 267 | + * mxc_set_next_event(), the core has about 4 minutes | |
| 268 | + * to call mxc_set_next_event() or shutdown clock after | |
| 269 | + * mode switching | |
| 270 | + */ | |
| 271 | + local_irq_save(flags); | |
| 272 | + imxtm->gpt->gpt_irq_enable(imxtm); | |
| 273 | + local_irq_restore(flags); | |
| 274 | + break; | |
| 275 | + case CLOCK_EVT_MODE_SHUTDOWN: | |
| 276 | + case CLOCK_EVT_MODE_UNUSED: | |
| 277 | + case CLOCK_EVT_MODE_RESUME: | |
| 278 | + /* Left event sources disabled, no more interrupts appear */ | |
| 279 | + break; | |
| 280 | + } | |
| 281 | +} | |
| 282 | + | |
| 283 | +/* | |
| 284 | + * IRQ handler for the timer | |
| 285 | + */ | |
| 286 | +static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) | |
| 287 | +{ | |
| 288 | + struct clock_event_device *ced = dev_id; | |
| 289 | + struct imx_timer *imxtm = to_imx_timer(ced); | |
| 290 | + uint32_t tstat; | |
| 291 | + | |
| 292 | + tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat); | |
| 293 | + | |
| 294 | + imxtm->gpt->gpt_irq_acknowledge(imxtm); | |
| 295 | + | |
| 296 | + ced->event_handler(ced); | |
| 297 | + | |
| 298 | + return IRQ_HANDLED; | |
| 299 | +} | |
| 300 | + | |
| 301 | +static int __init mxc_clockevent_init(struct imx_timer *imxtm) | |
| 302 | +{ | |
| 303 | + struct clock_event_device *ced = &imxtm->ced; | |
| 304 | + struct irqaction *act = &imxtm->act; | |
| 305 | + | |
| 306 | + imxtm->cem = CLOCK_EVT_MODE_UNUSED; | |
| 307 | + | |
| 308 | + ced->name = "mxc_timer1"; | |
| 309 | + ced->features = CLOCK_EVT_FEAT_ONESHOT; | |
| 310 | + ced->set_mode = mxc_set_mode; | |
| 311 | + ced->set_next_event = imxtm->gpt->set_next_event; | |
| 312 | + ced->rating = 200; | |
| 313 | + ced->cpumask = cpumask_of(0); | |
| 314 | + clockevents_config_and_register(ced, clk_get_rate(imxtm->clk_per), | |
| 315 | + 0xff, 0xfffffffe); | |
| 316 | + | |
| 317 | + act->name = "i.MX Timer Tick"; | |
| 318 | + act->flags = IRQF_TIMER | IRQF_IRQPOLL; | |
| 319 | + act->handler = mxc_timer_interrupt; | |
| 320 | + act->dev_id = ced; | |
| 321 | + | |
| 322 | + return setup_irq(imxtm->irq, act); | |
| 323 | +} | |
| 324 | + | |
| 325 | +static void imx1_gpt_setup_tctl(struct imx_timer *imxtm) | |
| 326 | +{ | |
| 327 | + u32 tctl_val; | |
| 328 | + | |
| 329 | + tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; | |
| 330 | + writel_relaxed(tctl_val, imxtm->base + MXC_TCTL); | |
| 331 | +} | |
| 332 | +#define imx21_gpt_setup_tctl imx1_gpt_setup_tctl | |
| 333 | + | |
| 334 | +static void imx31_gpt_setup_tctl(struct imx_timer *imxtm) | |
| 335 | +{ | |
| 336 | + u32 tctl_val; | |
| 337 | + | |
| 338 | + tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; | |
| 339 | + if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8) | |
| 340 | + tctl_val |= V2_TCTL_CLK_OSC_DIV8; | |
| 341 | + else | |
| 342 | + tctl_val |= V2_TCTL_CLK_PER; | |
| 343 | + | |
| 344 | + writel_relaxed(tctl_val, imxtm->base + MXC_TCTL); | |
| 345 | +} | |
| 346 | + | |
| 347 | +static void imx6dl_gpt_setup_tctl(struct imx_timer *imxtm) | |
| 348 | +{ | |
| 349 | + u32 tctl_val; | |
| 350 | + | |
| 351 | + tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; | |
| 352 | + if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8) { | |
| 353 | + tctl_val |= V2_TCTL_CLK_OSC_DIV8; | |
| 354 | + /* 24 / 8 = 3 MHz */ | |
| 355 | + writel_relaxed(7 << V2_TPRER_PRE24M, imxtm->base + MXC_TPRER); | |
| 356 | + tctl_val |= V2_TCTL_24MEN; | |
| 357 | + } else { | |
| 358 | + tctl_val |= V2_TCTL_CLK_PER; | |
| 359 | + } | |
| 360 | + | |
| 361 | + writel_relaxed(tctl_val, imxtm->base + MXC_TCTL); | |
| 362 | +} | |
| 363 | + | |
| 364 | +static const struct imx_gpt_data imx1_gpt_data = { | |
| 365 | + .reg_tstat = MX1_2_TSTAT, | |
| 366 | + .reg_tcn = MX1_2_TCN, | |
| 367 | + .reg_tcmp = MX1_2_TCMP, | |
| 368 | + .gpt_irq_enable = imx1_gpt_irq_enable, | |
| 369 | + .gpt_irq_disable = imx1_gpt_irq_disable, | |
| 370 | + .gpt_irq_acknowledge = imx1_gpt_irq_acknowledge, | |
| 371 | + .gpt_setup_tctl = imx1_gpt_setup_tctl, | |
| 372 | + .set_next_event = mx1_2_set_next_event, | |
| 373 | +}; | |
| 374 | + | |
| 375 | +static const struct imx_gpt_data imx21_gpt_data = { | |
| 376 | + .reg_tstat = MX1_2_TSTAT, | |
| 377 | + .reg_tcn = MX1_2_TCN, | |
| 378 | + .reg_tcmp = MX1_2_TCMP, | |
| 379 | + .gpt_irq_enable = imx21_gpt_irq_enable, | |
| 380 | + .gpt_irq_disable = imx21_gpt_irq_disable, | |
| 381 | + .gpt_irq_acknowledge = imx21_gpt_irq_acknowledge, | |
| 382 | + .gpt_setup_tctl = imx21_gpt_setup_tctl, | |
| 383 | + .set_next_event = mx1_2_set_next_event, | |
| 384 | +}; | |
| 385 | + | |
| 386 | +static const struct imx_gpt_data imx31_gpt_data = { | |
| 387 | + .reg_tstat = V2_TSTAT, | |
| 388 | + .reg_tcn = V2_TCN, | |
| 389 | + .reg_tcmp = V2_TCMP, | |
| 390 | + .gpt_irq_enable = imx31_gpt_irq_enable, | |
| 391 | + .gpt_irq_disable = imx31_gpt_irq_disable, | |
| 392 | + .gpt_irq_acknowledge = imx31_gpt_irq_acknowledge, | |
| 393 | + .gpt_setup_tctl = imx31_gpt_setup_tctl, | |
| 394 | + .set_next_event = v2_set_next_event, | |
| 395 | +}; | |
| 396 | + | |
| 397 | +static const struct imx_gpt_data imx6dl_gpt_data = { | |
| 398 | + .reg_tstat = V2_TSTAT, | |
| 399 | + .reg_tcn = V2_TCN, | |
| 400 | + .reg_tcmp = V2_TCMP, | |
| 401 | + .gpt_irq_enable = imx6dl_gpt_irq_enable, | |
| 402 | + .gpt_irq_disable = imx6dl_gpt_irq_disable, | |
| 403 | + .gpt_irq_acknowledge = imx6dl_gpt_irq_acknowledge, | |
| 404 | + .gpt_setup_tctl = imx6dl_gpt_setup_tctl, | |
| 405 | + .set_next_event = v2_set_next_event, | |
| 406 | +}; | |
| 407 | + | |
| 408 | +static void __init _mxc_timer_init(struct imx_timer *imxtm) | |
| 409 | +{ | |
| 410 | + switch (imxtm->type) { | |
| 411 | + case GPT_TYPE_IMX1: | |
| 412 | + imxtm->gpt = &imx1_gpt_data; | |
| 413 | + break; | |
| 414 | + case GPT_TYPE_IMX21: | |
| 415 | + imxtm->gpt = &imx21_gpt_data; | |
| 416 | + break; | |
| 417 | + case GPT_TYPE_IMX31: | |
| 418 | + imxtm->gpt = &imx31_gpt_data; | |
| 419 | + break; | |
| 420 | + case GPT_TYPE_IMX6DL: | |
| 421 | + imxtm->gpt = &imx6dl_gpt_data; | |
| 422 | + break; | |
| 423 | + default: | |
| 424 | + BUG(); | |
| 425 | + } | |
| 426 | + | |
| 427 | + if (IS_ERR(imxtm->clk_per)) { | |
| 428 | + pr_err("i.MX timer: unable to get clk\n"); | |
| 429 | + return; | |
| 430 | + } | |
| 431 | + | |
| 432 | + if (!IS_ERR(imxtm->clk_ipg)) | |
| 433 | + clk_prepare_enable(imxtm->clk_ipg); | |
| 434 | + | |
| 435 | + clk_prepare_enable(imxtm->clk_per); | |
| 436 | + | |
| 437 | + /* | |
| 438 | + * Initialise to a known state (all timers off, and timing reset) | |
| 439 | + */ | |
| 440 | + | |
| 441 | + writel_relaxed(0, imxtm->base + MXC_TCTL); | |
| 442 | + writel_relaxed(0, imxtm->base + MXC_TPRER); /* see datasheet note */ | |
| 443 | + | |
| 444 | + imxtm->gpt->gpt_setup_tctl(imxtm); | |
| 445 | + | |
| 446 | + /* init and register the timer to the framework */ | |
| 447 | + mxc_clocksource_init(imxtm); | |
| 448 | + mxc_clockevent_init(imxtm); | |
| 449 | +} | |
| 450 | + | |
| 451 | +void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type) | |
| 452 | +{ | |
| 453 | + struct imx_timer *imxtm; | |
| 454 | + | |
| 455 | + imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL); | |
| 456 | + BUG_ON(!imxtm); | |
| 457 | + | |
| 458 | + imxtm->clk_per = clk_get_sys("imx-gpt.0", "per"); | |
| 459 | + imxtm->clk_ipg = clk_get_sys("imx-gpt.0", "ipg"); | |
| 460 | + | |
| 461 | + imxtm->base = ioremap(pbase, SZ_4K); | |
| 462 | + BUG_ON(!imxtm->base); | |
| 463 | + | |
| 464 | + imxtm->type = type; | |
| 465 | + | |
| 466 | + _mxc_timer_init(imxtm); | |
| 467 | +} | |
| 468 | + | |
| 469 | +static void __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type type) | |
| 470 | +{ | |
| 471 | + struct imx_timer *imxtm; | |
| 472 | + static int initialized; | |
| 473 | + | |
| 474 | + /* Support one instance only */ | |
| 475 | + if (initialized) | |
| 476 | + return; | |
| 477 | + | |
| 478 | + imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL); | |
| 479 | + BUG_ON(!imxtm); | |
| 480 | + | |
| 481 | + imxtm->base = of_iomap(np, 0); | |
| 482 | + WARN_ON(!imxtm->base); | |
| 483 | + imxtm->irq = irq_of_parse_and_map(np, 0); | |
| 484 | + | |
| 485 | + imxtm->clk_ipg = of_clk_get_by_name(np, "ipg"); | |
| 486 | + | |
| 487 | + /* Try osc_per first, and fall back to per otherwise */ | |
| 488 | + imxtm->clk_per = of_clk_get_by_name(np, "osc_per"); | |
| 489 | + if (IS_ERR(imxtm->clk_per)) | |
| 490 | + imxtm->clk_per = of_clk_get_by_name(np, "per"); | |
| 491 | + | |
| 492 | + imxtm->type = type; | |
| 493 | + | |
| 494 | + _mxc_timer_init(imxtm); | |
| 495 | + | |
| 496 | + initialized = 1; | |
| 497 | +} | |
| 498 | + | |
| 499 | +static void __init imx1_timer_init_dt(struct device_node *np) | |
| 500 | +{ | |
| 501 | + mxc_timer_init_dt(np, GPT_TYPE_IMX1); | |
| 502 | +} | |
| 503 | + | |
| 504 | +static void __init imx21_timer_init_dt(struct device_node *np) | |
| 505 | +{ | |
| 506 | + mxc_timer_init_dt(np, GPT_TYPE_IMX21); | |
| 507 | +} | |
| 508 | + | |
| 509 | +static void __init imx31_timer_init_dt(struct device_node *np) | |
| 510 | +{ | |
| 511 | + enum imx_gpt_type type = GPT_TYPE_IMX31; | |
| 512 | + | |
| 513 | + /* | |
| 514 | + * We were using the same compatible string for i.MX6Q/D and i.MX6DL/S | |
| 515 | + * GPT device, while they actually have different programming model. | |
| 516 | + * This is a workaround to keep the existing i.MX6DL/S DTBs continue | |
| 517 | + * working with the new kernel. | |
| 518 | + */ | |
| 519 | + if (of_machine_is_compatible("fsl,imx6dl")) | |
| 520 | + type = GPT_TYPE_IMX6DL; | |
| 521 | + | |
| 522 | + mxc_timer_init_dt(np, type); | |
| 523 | +} | |
| 524 | + | |
| 525 | +static void __init imx6dl_timer_init_dt(struct device_node *np) | |
| 526 | +{ | |
| 527 | + mxc_timer_init_dt(np, GPT_TYPE_IMX6DL); | |
| 528 | +} | |
| 529 | + | |
| 530 | +CLOCKSOURCE_OF_DECLARE(imx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt); | |
| 531 | +CLOCKSOURCE_OF_DECLARE(imx21_timer, "fsl,imx21-gpt", imx21_timer_init_dt); | |
| 532 | +CLOCKSOURCE_OF_DECLARE(imx31_timer, "fsl,imx31-gpt", imx31_timer_init_dt); | |
| 533 | +CLOCKSOURCE_OF_DECLARE(imx25_timer, "fsl,imx25-gpt", imx31_timer_init_dt); | |
| 534 | +CLOCKSOURCE_OF_DECLARE(imx50_timer, "fsl,imx50-gpt", imx31_timer_init_dt); | |
| 535 | +CLOCKSOURCE_OF_DECLARE(imx51_timer, "fsl,imx51-gpt", imx31_timer_init_dt); | |
| 536 | +CLOCKSOURCE_OF_DECLARE(imx53_timer, "fsl,imx53-gpt", imx31_timer_init_dt); | |
| 537 | +CLOCKSOURCE_OF_DECLARE(imx6q_timer, "fsl,imx6q-gpt", imx31_timer_init_dt); | |
| 538 | +CLOCKSOURCE_OF_DECLARE(imx6dl_timer, "fsl,imx6dl-gpt", imx6dl_timer_init_dt); | |
| 539 | +CLOCKSOURCE_OF_DECLARE(imx6sl_timer, "fsl,imx6sl-gpt", imx6dl_timer_init_dt); | |
| 540 | +CLOCKSOURCE_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt); | |
| @@ -49,6 +49,14 @@ config OMAP_GPMC · 48 unmodified lines | ||
| 49 | 49 | interfacing to a variety of asynchronous as well as synchronous |
| 50 | 50 | memory drives like NOR, NAND, OneNAND, SRAM. |
| 51 | 51 | |
| 52 | +config OMAP_GPMC_DEBUG | |
| 53 | + bool | |
| 54 | + depends on OMAP_GPMC | |
| 55 | + help | |
| 56 | + Enables verbose debugging mostly to decode the bootloader provided | |
| 57 | + timings. Enable this during development to configure devices | |
| 58 | + connected to the GPMC bus. | |
| 59 | + | |
| 52 | 60 | config MVEBU_DEVBUS |
| 53 | 61 | bool "Marvell EBU Device Bus Controller" |
| 54 | 62 | default y |
| @@ -403,7 +403,7 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) · 402 unmodified lines | ||
| 403 | 403 | p->cycle2cyclediffcsen); |
| 404 | 404 | } |
| 405 | 405 | |
| 406 | −#ifdef DEBUG | |
| 406 | +#ifdef CONFIG_OMAP_GPMC_DEBUG | |
| 407 | 407 | /** |
| 408 | 408 | * get_gpmc_timing_reg - read a timing parameter and print DTS settings for it. |
| 409 | 409 | * @cs: Chip Select Region |
| @@ -612,7 +612,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max · 202 unmodified lines | ||
| 612 | 612 | } |
| 613 | 613 | |
| 614 | 614 | l = gpmc_cs_read_reg(cs, reg); |
| 615 | −#ifdef DEBUG | |
| 615 | +#ifdef CONFIG_OMAP_GPMC_DEBUG | |
| 616 | 616 | pr_info( |
| 617 | 617 | "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", |
| 618 | 618 | cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000, |
| @@ -767,7 +767,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, · 148 unmodified lines | ||
| 767 | 767 | GPMC_CONFIG1_CLKACTIVATIONTIME_MAX, |
| 768 | 768 | clk_activation, GPMC_CD_FCLK); |
| 769 | 769 | |
| 770 | −#ifdef DEBUG | |
| 770 | +#ifdef CONFIG_OMAP_GPMC_DEBUG | |
| 771 | 771 | pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n", |
| 772 | 772 | cs, (div * gpmc_get_fclk_period()) / 1000, div); |
| 773 | 773 | #endif |
| @@ -59,6 +59,7 @@ static u32 tegra20_fuse_readl(const unsigned int offset) · 58 unmodified lines | ||
| 59 | 59 | int ret; |
| 60 | 60 | u32 val = 0; |
| 61 | 61 | struct dma_async_tx_descriptor *dma_desc; |
| 62 | + unsigned long time_left; | |
| 62 | 63 | |
| 63 | 64 | mutex_lock(&apb_dma_lock); |
| 64 | 65 | |
| @@ -82,9 +83,10 @@ static u32 tegra20_fuse_readl(const unsigned int offset) · 17 unmodified lines | ||
| 82 | 83 | |
| 83 | 84 | dmaengine_submit(dma_desc); |
| 84 | 85 | dma_async_issue_pending(apb_dma_chan); |
| 85 | − ret = wait_for_completion_timeout(&apb_dma_wait, msecs_to_jiffies(50)); | |
| 86 | + time_left = wait_for_completion_timeout(&apb_dma_wait, | |
| 87 | + msecs_to_jiffies(50)); | |
| 86 | 88 | |
| 87 | − if (WARN(ret == 0, "apb read dma timed out")) | |
| 89 | + if (WARN(time_left == 0, "apb read dma timed out")) | |
| 88 | 90 | dmaengine_terminate_all(apb_dma_chan); |
| 89 | 91 | else |
| 90 | 92 | val = *apb_buffer; |
| @@ -377,13 +377,10 @@ int tegra_pmc_cpu_remove_clamping(int cpuid) · 376 unmodified lines | ||
| 377 | 377 | } |
| 378 | 378 | #endif /* CONFIG_SMP */ |
| 379 | 379 | |
| 380 | −/** | |
| 381 | − * tegra_pmc_restart() - reboot the system | |
| 382 | − * @mode: which mode to reboot in | |
| 383 | − * @cmd: reboot command | |
| 384 | − */ | |
| 385 | −void tegra_pmc_restart(enum reboot_mode mode, const char *cmd) | |
| 380 | +static int tegra_pmc_restart_notify(struct notifier_block *this, | |
| 381 | + unsigned long action, void *data) | |
| 386 | 382 | { |
| 383 | + const char *cmd = data; | |
| 387 | 384 | u32 value; |
| 388 | 385 | |
| 389 | 386 | value = tegra_pmc_readl(PMC_SCRATCH0); |
| @@ -405,8 +402,15 @@ void tegra_pmc_restart(enum reboot_mode mode, const char *cmd) · 15 unmodified lines | ||
| 405 | 402 | value = tegra_pmc_readl(0); |
| 406 | 403 | value |= 0x10; |
| 407 | 404 | tegra_pmc_writel(value, 0); |
| 405 | + | |
| 406 | + return NOTIFY_DONE; | |
| 408 | 407 | } |
| 409 | 408 | |
| 409 | +static struct notifier_block tegra_pmc_restart_handler = { | |
| 410 | + .notifier_call = tegra_pmc_restart_notify, | |
| 411 | + .priority = 128, | |
| 412 | +}; | |
| 413 | + | |
| 410 | 414 | static int powergate_show(struct seq_file *s, void *data) |
| 411 | 415 | { |
| 412 | 416 | unsigned int i; |
| @@ -837,6 +841,13 @@ static int tegra_pmc_probe(struct platform_device *pdev) · 424 unmodified lines | ||
| 837 | 841 | return err; |
| 838 | 842 | } |
| 839 | 843 | |
| 844 | + err = register_restart_handler(&tegra_pmc_restart_handler); | |
| 845 | + if (err) { | |
| 846 | + dev_err(&pdev->dev, "unable to register restart handler, %d\n", | |
| 847 | + err); | |
| 848 | + return err; | |
| 849 | + } | |
| 850 | + | |
| 840 | 851 | return 0; |
| 841 | 852 | } |
| 842 | 853 | |
| @@ -13,20 +13,25 @@ · 12 unmodified lines | ||
| 13 | 13 | * option) any later version. |
| 14 | 14 | */ |
| 15 | 15 | |
| 16 | +#include <linux/delay.h> | |
| 17 | +#include <linux/reboot.h> | |
| 16 | 18 | #include <linux/types.h> |
| 17 | 19 | #include <linux/module.h> |
| 18 | 20 | #include <linux/io.h> |
| 19 | 21 | #include <linux/watchdog.h> |
| 20 | 22 | #include <linux/platform_device.h> |
| 21 | 23 | #include <linux/of_address.h> |
| 24 | +#include <linux/of_platform.h> | |
| 22 | 25 | |
| 23 | 26 | #define PM_RSTC 0x1c |
| 27 | +#define PM_RSTS 0x20 | |
| 24 | 28 | #define PM_WDOG 0x24 |
| 25 | 29 | |
| 26 | 30 | #define PM_PASSWORD 0x5a000000 |
| 27 | 31 | |
| 28 | 32 | #define PM_WDOG_TIME_SET 0x000fffff |
| 29 | 33 | #define PM_RSTC_WRCFG_CLR 0xffffffcf |
| 34 | +#define PM_RSTS_HADWRH_SET 0x00000040 | |
| 30 | 35 | #define PM_RSTC_WRCFG_SET 0x00000030 |
| 31 | 36 | #define PM_RSTC_WRCFG_FULL_RESET 0x00000020 |
| 32 | 37 | #define PM_RSTC_RESET 0x00000102 |
| @@ -37,6 +42,7 @@ · 4 unmodified lines | ||
| 37 | 42 | struct bcm2835_wdt { |
| 38 | 43 | void __iomem *base; |
| 39 | 44 | spinlock_t lock; |
| 45 | + struct notifier_block restart_handler; | |
| 40 | 46 | }; |
| 41 | 47 | |
| 42 | 48 | static unsigned int heartbeat; |
| @@ -106,6 +112,53 @@ static struct watchdog_device bcm2835_wdt_wdd = { · 63 unmodified lines | ||
| 106 | 112 | .timeout = WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET), |
| 107 | 113 | }; |
| 108 | 114 | |
| 115 | +static int | |
| 116 | +bcm2835_restart(struct notifier_block *this, unsigned long mode, void *cmd) | |
| 117 | +{ | |
| 118 | + struct bcm2835_wdt *wdt = container_of(this, struct bcm2835_wdt, | |
| 119 | + restart_handler); | |
| 120 | + u32 val; | |
| 121 | + | |
| 122 | + /* use a timeout of 10 ticks (~150us) */ | |
| 123 | + writel_relaxed(10 | PM_PASSWORD, wdt->base + PM_WDOG); | |
| 124 | + val = readl_relaxed(wdt->base + PM_RSTC); | |
| 125 | + val &= PM_RSTC_WRCFG_CLR; | |
| 126 | + val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET; | |
| 127 | + writel_relaxed(val, wdt->base + PM_RSTC); | |
| 128 | + | |
| 129 | + /* No sleeping, possibly atomic. */ | |
| 130 | + mdelay(1); | |
| 131 | + | |
| 132 | + return 0; | |
| 133 | +} | |
| 134 | + | |
| 135 | +/* | |
| 136 | + * We can't really power off, but if we do the normal reset scheme, and | |
| 137 | + * indicate to bootcode.bin not to reboot, then most of the chip will be | |
| 138 | + * powered off. | |
| 139 | + */ | |
| 140 | +static void bcm2835_power_off(void) | |
| 141 | +{ | |
| 142 | + struct device_node *np = | |
| 143 | + of_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm-wdt"); | |
| 144 | + struct platform_device *pdev = of_find_device_by_node(np); | |
| 145 | + struct bcm2835_wdt *wdt = platform_get_drvdata(pdev); | |
| 146 | + u32 val; | |
| 147 | + | |
| 148 | + /* | |
| 149 | + * We set the watchdog hard reset bit here to distinguish this reset | |
| 150 | + * from the normal (full) reset. bootcode.bin will not reboot after a | |
| 151 | + * hard reset. | |
| 152 | + */ | |
| 153 | + val = readl_relaxed(wdt->base + PM_RSTS); | |
| 154 | + val &= PM_RSTC_WRCFG_CLR; | |
| 155 | + val |= PM_PASSWORD | PM_RSTS_HADWRH_SET; | |
| 156 | + writel_relaxed(val, wdt->base + PM_RSTS); | |
| 157 | + | |
| 158 | + /* Continue with normal reset mechanism */ | |
| 159 | + bcm2835_restart(&wdt->restart_handler, REBOOT_HARD, NULL); | |
| 160 | +} | |
| 161 | + | |
| 109 | 162 | static int bcm2835_wdt_probe(struct platform_device *pdev) |
| 110 | 163 | { |
| 111 | 164 | struct device *dev = &pdev->dev; |
| @@ -136,6 +189,12 @@ static int bcm2835_wdt_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 136 | 189 | return err; |
| 137 | 190 | } |
| 138 | 191 | |
| 192 | + wdt->restart_handler.notifier_call = bcm2835_restart; | |
| 193 | + wdt->restart_handler.priority = 128; | |
| 194 | + register_restart_handler(&wdt->restart_handler); | |
| 195 | + if (pm_power_off == NULL) | |
| 196 | + pm_power_off = bcm2835_power_off; | |
| 197 | + | |
| 139 | 198 | dev_info(dev, "Broadcom BCM2835 watchdog timer"); |
| 140 | 199 | return 0; |
| 141 | 200 | } |
| @@ -144,6 +203,9 @@ static int bcm2835_wdt_remove(struct platform_device *pdev) · 2 unmodified lines | ||
| 144 | 203 | { |
| 145 | 204 | struct bcm2835_wdt *wdt = platform_get_drvdata(pdev); |
| 146 | 205 | |
| 206 | + unregister_restart_handler(&wdt->restart_handler); | |
| 207 | + if (pm_power_off == bcm2835_power_off) | |
| 208 | + pm_power_off = NULL; | |
| 147 | 209 | watchdog_unregister_device(&bcm2835_wdt_wdd); |
| 148 | 210 | iounmap(wdt->base); |
| 149 | 211 | |
| @@ -0,0 +1,450 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2014-2015 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 | + | |
| 10 | +#ifndef __DT_BINDINGS_CLOCK_IMX7D_H | |
| 11 | +#define __DT_BINDINGS_CLOCK_IMX7D_H | |
| 12 | + | |
| 13 | +#define IMX7D_OSC_24M_CLK 0 | |
| 14 | +#define IMX7D_PLL_ARM_MAIN 1 | |
| 15 | +#define IMX7D_PLL_ARM_MAIN_CLK 2 | |
| 16 | +#define IMX7D_PLL_ARM_MAIN_SRC 3 | |
| 17 | +#define IMX7D_PLL_ARM_MAIN_BYPASS 4 | |
| 18 | +#define IMX7D_PLL_SYS_MAIN 5 | |
| 19 | +#define IMX7D_PLL_SYS_MAIN_CLK 6 | |
| 20 | +#define IMX7D_PLL_SYS_MAIN_SRC 7 | |
| 21 | +#define IMX7D_PLL_SYS_MAIN_BYPASS 8 | |
| 22 | +#define IMX7D_PLL_SYS_MAIN_480M 9 | |
| 23 | +#define IMX7D_PLL_SYS_MAIN_240M 10 | |
| 24 | +#define IMX7D_PLL_SYS_MAIN_120M 11 | |
| 25 | +#define IMX7D_PLL_SYS_MAIN_480M_CLK 12 | |
| 26 | +#define IMX7D_PLL_SYS_MAIN_240M_CLK 13 | |
| 27 | +#define IMX7D_PLL_SYS_MAIN_120M_CLK 14 | |
| 28 | +#define IMX7D_PLL_SYS_PFD0_392M_CLK 15 | |
| 29 | +#define IMX7D_PLL_SYS_PFD0_196M 16 | |
| 30 | +#define IMX7D_PLL_SYS_PFD0_196M_CLK 17 | |
| 31 | +#define IMX7D_PLL_SYS_PFD1_332M_CLK 18 | |
| 32 | +#define IMX7D_PLL_SYS_PFD1_166M 19 | |
| 33 | +#define IMX7D_PLL_SYS_PFD1_166M_CLK 20 | |
| 34 | +#define IMX7D_PLL_SYS_PFD2_270M_CLK 21 | |
| 35 | +#define IMX7D_PLL_SYS_PFD2_135M 22 | |
| 36 | +#define IMX7D_PLL_SYS_PFD2_135M_CLK 23 | |
| 37 | +#define IMX7D_PLL_SYS_PFD3_CLK 24 | |
| 38 | +#define IMX7D_PLL_SYS_PFD4_CLK 25 | |
| 39 | +#define IMX7D_PLL_SYS_PFD5_CLK 26 | |
| 40 | +#define IMX7D_PLL_SYS_PFD6_CLK 27 | |
| 41 | +#define IMX7D_PLL_SYS_PFD7_CLK 28 | |
| 42 | +#define IMX7D_PLL_ENET_MAIN 29 | |
| 43 | +#define IMX7D_PLL_ENET_MAIN_CLK 30 | |
| 44 | +#define IMX7D_PLL_ENET_MAIN_SRC 31 | |
| 45 | +#define IMX7D_PLL_ENET_MAIN_BYPASS 32 | |
| 46 | +#define IMX7D_PLL_ENET_MAIN_500M 33 | |
| 47 | +#define IMX7D_PLL_ENET_MAIN_250M 34 | |
| 48 | +#define IMX7D_PLL_ENET_MAIN_125M 35 | |
| 49 | +#define IMX7D_PLL_ENET_MAIN_100M 36 | |
| 50 | +#define IMX7D_PLL_ENET_MAIN_50M 37 | |
| 51 | +#define IMX7D_PLL_ENET_MAIN_40M 38 | |
| 52 | +#define IMX7D_PLL_ENET_MAIN_25M 39 | |
| 53 | +#define IMX7D_PLL_ENET_MAIN_500M_CLK 40 | |
| 54 | +#define IMX7D_PLL_ENET_MAIN_250M_CLK 41 | |
| 55 | +#define IMX7D_PLL_ENET_MAIN_125M_CLK 42 | |
| 56 | +#define IMX7D_PLL_ENET_MAIN_100M_CLK 43 | |
| 57 | +#define IMX7D_PLL_ENET_MAIN_50M_CLK 44 | |
| 58 | +#define IMX7D_PLL_ENET_MAIN_40M_CLK 45 | |
| 59 | +#define IMX7D_PLL_ENET_MAIN_25M_CLK 46 | |
| 60 | +#define IMX7D_PLL_DRAM_MAIN 47 | |
| 61 | +#define IMX7D_PLL_DRAM_MAIN_CLK 48 | |
| 62 | +#define IMX7D_PLL_DRAM_MAIN_SRC 49 | |
| 63 | +#define IMX7D_PLL_DRAM_MAIN_BYPASS 50 | |
| 64 | +#define IMX7D_PLL_DRAM_MAIN_533M 51 | |
| 65 | +#define IMX7D_PLL_DRAM_MAIN_533M_CLK 52 | |
| 66 | +#define IMX7D_PLL_AUDIO_MAIN 53 | |
| 67 | +#define IMX7D_PLL_AUDIO_MAIN_CLK 54 | |
| 68 | +#define IMX7D_PLL_AUDIO_MAIN_SRC 55 | |
| 69 | +#define IMX7D_PLL_AUDIO_MAIN_BYPASS 56 | |
| 70 | +#define IMX7D_PLL_VIDEO_MAIN_CLK 57 | |
| 71 | +#define IMX7D_PLL_VIDEO_MAIN 58 | |
| 72 | +#define IMX7D_PLL_VIDEO_MAIN_SRC 59 | |
| 73 | +#define IMX7D_PLL_VIDEO_MAIN_BYPASS 60 | |
| 74 | +#define IMX7D_USB_MAIN_480M_CLK 61 | |
| 75 | +#define IMX7D_ARM_A7_ROOT_CLK 62 | |
| 76 | +#define IMX7D_ARM_A7_ROOT_SRC 63 | |
| 77 | +#define IMX7D_ARM_A7_ROOT_CG 64 | |
| 78 | +#define IMX7D_ARM_A7_ROOT_DIV 65 | |
| 79 | +#define IMX7D_ARM_M4_ROOT_CLK 66 | |
| 80 | +#define IMX7D_ARM_M4_ROOT_SRC 67 | |
| 81 | +#define IMX7D_ARM_M4_ROOT_CG 68 | |
| 82 | +#define IMX7D_ARM_M4_ROOT_DIV 69 | |
| 83 | +#define IMX7D_ARM_M0_ROOT_CLK 70 | |
| 84 | +#define IMX7D_ARM_M0_ROOT_SRC 71 | |
| 85 | +#define IMX7D_ARM_M0_ROOT_CG 72 | |
| 86 | +#define IMX7D_ARM_M0_ROOT_DIV 73 | |
| 87 | +#define IMX7D_MAIN_AXI_ROOT_CLK 74 | |
| 88 | +#define IMX7D_MAIN_AXI_ROOT_SRC 75 | |
| 89 | +#define IMX7D_MAIN_AXI_ROOT_CG 76 | |
| 90 | +#define IMX7D_MAIN_AXI_ROOT_DIV 77 | |
| 91 | +#define IMX7D_DISP_AXI_ROOT_CLK 78 | |
| 92 | +#define IMX7D_DISP_AXI_ROOT_SRC 79 | |
| 93 | +#define IMX7D_DISP_AXI_ROOT_CG 80 | |
| 94 | +#define IMX7D_DISP_AXI_ROOT_DIV 81 | |
| 95 | +#define IMX7D_ENET_AXI_ROOT_CLK 82 | |
| 96 | +#define IMX7D_ENET_AXI_ROOT_SRC 83 | |
| 97 | +#define IMX7D_ENET_AXI_ROOT_CG 84 | |
| 98 | +#define IMX7D_ENET_AXI_ROOT_DIV 85 | |
| 99 | +#define IMX7D_NAND_USDHC_BUS_ROOT_CLK 86 | |
| 100 | +#define IMX7D_NAND_USDHC_BUS_ROOT_SRC 87 | |
| 101 | +#define IMX7D_NAND_USDHC_BUS_ROOT_CG 88 | |
| 102 | +#define IMX7D_NAND_USDHC_BUS_ROOT_DIV 89 | |
| 103 | +#define IMX7D_AHB_CHANNEL_ROOT_CLK 90 | |
| 104 | +#define IMX7D_AHB_CHANNEL_ROOT_SRC 91 | |
| 105 | +#define IMX7D_AHB_CHANNEL_ROOT_CG 92 | |
| 106 | +#define IMX7D_AHB_CHANNEL_ROOT_DIV 93 | |
| 107 | +#define IMX7D_DRAM_PHYM_ROOT_CLK 94 | |
| 108 | +#define IMX7D_DRAM_PHYM_ROOT_SRC 95 | |
| 109 | +#define IMX7D_DRAM_PHYM_ROOT_CG 96 | |
| 110 | +#define IMX7D_DRAM_PHYM_ROOT_DIV 97 | |
| 111 | +#define IMX7D_DRAM_ROOT_CLK 98 | |
| 112 | +#define IMX7D_DRAM_ROOT_SRC 99 | |
| 113 | +#define IMX7D_DRAM_ROOT_CG 100 | |
| 114 | +#define IMX7D_DRAM_ROOT_DIV 101 | |
| 115 | +#define IMX7D_DRAM_PHYM_ALT_ROOT_CLK 102 | |
| 116 | +#define IMX7D_DRAM_PHYM_ALT_ROOT_SRC 103 | |
| 117 | +#define IMX7D_DRAM_PHYM_ALT_ROOT_CG 104 | |
| 118 | +#define IMX7D_DRAM_PHYM_ALT_ROOT_DIV 105 | |
| 119 | +#define IMX7D_DRAM_ALT_ROOT_CLK 106 | |
| 120 | +#define IMX7D_DRAM_ALT_ROOT_SRC 107 | |
| 121 | +#define IMX7D_DRAM_ALT_ROOT_CG 108 | |
| 122 | +#define IMX7D_DRAM_ALT_ROOT_DIV 109 | |
| 123 | +#define IMX7D_USB_HSIC_ROOT_CLK 110 | |
| 124 | +#define IMX7D_USB_HSIC_ROOT_SRC 111 | |
| 125 | +#define IMX7D_USB_HSIC_ROOT_CG 112 | |
| 126 | +#define IMX7D_USB_HSIC_ROOT_DIV 113 | |
| 127 | +#define IMX7D_PCIE_CTRL_ROOT_CLK 114 | |
| 128 | +#define IMX7D_PCIE_CTRL_ROOT_SRC 115 | |
| 129 | +#define IMX7D_PCIE_CTRL_ROOT_CG 116 | |
| 130 | +#define IMX7D_PCIE_CTRL_ROOT_DIV 117 | |
| 131 | +#define IMX7D_PCIE_PHY_ROOT_CLK 118 | |
| 132 | +#define IMX7D_PCIE_PHY_ROOT_SRC 119 | |
| 133 | +#define IMX7D_PCIE_PHY_ROOT_CG 120 | |
| 134 | +#define IMX7D_PCIE_PHY_ROOT_DIV 121 | |
| 135 | +#define IMX7D_EPDC_PIXEL_ROOT_CLK 122 | |
| 136 | +#define IMX7D_EPDC_PIXEL_ROOT_SRC 123 | |
| 137 | +#define IMX7D_EPDC_PIXEL_ROOT_CG 124 | |
| 138 | +#define IMX7D_EPDC_PIXEL_ROOT_DIV 125 | |
| 139 | +#define IMX7D_LCDIF_PIXEL_ROOT_CLK 126 | |
| 140 | +#define IMX7D_LCDIF_PIXEL_ROOT_SRC 127 | |
| 141 | +#define IMX7D_LCDIF_PIXEL_ROOT_CG 128 | |
| 142 | +#define IMX7D_LCDIF_PIXEL_ROOT_DIV 129 | |
| 143 | +#define IMX7D_MIPI_DSI_ROOT_CLK 130 | |
| 144 | +#define IMX7D_MIPI_DSI_ROOT_SRC 131 | |
| 145 | +#define IMX7D_MIPI_DSI_ROOT_CG 132 | |
| 146 | +#define IMX7D_MIPI_DSI_ROOT_DIV 133 | |
| 147 | +#define IMX7D_MIPI_CSI_ROOT_CLK 134 | |
| 148 | +#define IMX7D_MIPI_CSI_ROOT_SRC 135 | |
| 149 | +#define IMX7D_MIPI_CSI_ROOT_CG 136 | |
| 150 | +#define IMX7D_MIPI_CSI_ROOT_DIV 137 | |
| 151 | +#define IMX7D_MIPI_DPHY_ROOT_CLK 138 | |
| 152 | +#define IMX7D_MIPI_DPHY_ROOT_SRC 139 | |
| 153 | +#define IMX7D_MIPI_DPHY_ROOT_CG 140 | |
| 154 | +#define IMX7D_MIPI_DPHY_ROOT_DIV 141 | |
| 155 | +#define IMX7D_SAI1_ROOT_CLK 142 | |
| 156 | +#define IMX7D_SAI1_ROOT_SRC 143 | |
| 157 | +#define IMX7D_SAI1_ROOT_CG 144 | |
| 158 | +#define IMX7D_SAI1_ROOT_DIV 145 | |
| 159 | +#define IMX7D_SAI2_ROOT_CLK 146 | |
| 160 | +#define IMX7D_SAI2_ROOT_SRC 147 | |
| 161 | +#define IMX7D_SAI2_ROOT_CG 148 | |
| 162 | +#define IMX7D_SAI2_ROOT_DIV 149 | |
| 163 | +#define IMX7D_SAI3_ROOT_CLK 150 | |
| 164 | +#define IMX7D_SAI3_ROOT_SRC 151 | |
| 165 | +#define IMX7D_SAI3_ROOT_CG 152 | |
| 166 | +#define IMX7D_SAI3_ROOT_DIV 153 | |
| 167 | +#define IMX7D_SPDIF_ROOT_CLK 154 | |
| 168 | +#define IMX7D_SPDIF_ROOT_SRC 155 | |
| 169 | +#define IMX7D_SPDIF_ROOT_CG 156 | |
| 170 | +#define IMX7D_SPDIF_ROOT_DIV 157 | |
| 171 | +#define IMX7D_ENET1_REF_ROOT_CLK 158 | |
| 172 | +#define IMX7D_ENET1_REF_ROOT_SRC 159 | |
| 173 | +#define IMX7D_ENET1_REF_ROOT_CG 160 | |
| 174 | +#define IMX7D_ENET1_REF_ROOT_DIV 161 | |
| 175 | +#define IMX7D_ENET1_TIME_ROOT_CLK 162 | |
| 176 | +#define IMX7D_ENET1_TIME_ROOT_SRC 163 | |
| 177 | +#define IMX7D_ENET1_TIME_ROOT_CG 164 | |
| 178 | +#define IMX7D_ENET1_TIME_ROOT_DIV 165 | |
| 179 | +#define IMX7D_ENET2_REF_ROOT_CLK 166 | |
| 180 | +#define IMX7D_ENET2_REF_ROOT_SRC 167 | |
| 181 | +#define IMX7D_ENET2_REF_ROOT_CG 168 | |
| 182 | +#define IMX7D_ENET2_REF_ROOT_DIV 169 | |
| 183 | +#define IMX7D_ENET2_TIME_ROOT_CLK 170 | |
| 184 | +#define IMX7D_ENET2_TIME_ROOT_SRC 171 | |
| 185 | +#define IMX7D_ENET2_TIME_ROOT_CG 172 | |
| 186 | +#define IMX7D_ENET2_TIME_ROOT_DIV 173 | |
| 187 | +#define IMX7D_ENET_PHY_REF_ROOT_CLK 174 | |
| 188 | +#define IMX7D_ENET_PHY_REF_ROOT_SRC 175 | |
| 189 | +#define IMX7D_ENET_PHY_REF_ROOT_CG 176 | |
| 190 | +#define IMX7D_ENET_PHY_REF_ROOT_DIV 177 | |
| 191 | +#define IMX7D_EIM_ROOT_CLK 178 | |
| 192 | +#define IMX7D_EIM_ROOT_SRC 179 | |
| 193 | +#define IMX7D_EIM_ROOT_CG 180 | |
| 194 | +#define IMX7D_EIM_ROOT_DIV 181 | |
| 195 | +#define IMX7D_NAND_ROOT_CLK 182 | |
| 196 | +#define IMX7D_NAND_ROOT_SRC 183 | |
| 197 | +#define IMX7D_NAND_ROOT_CG 184 | |
| 198 | +#define IMX7D_NAND_ROOT_DIV 185 | |
| 199 | +#define IMX7D_QSPI_ROOT_CLK 186 | |
| 200 | +#define IMX7D_QSPI_ROOT_SRC 187 | |
| 201 | +#define IMX7D_QSPI_ROOT_CG 188 | |
| 202 | +#define IMX7D_QSPI_ROOT_DIV 189 | |
| 203 | +#define IMX7D_USDHC1_ROOT_CLK 190 | |
| 204 | +#define IMX7D_USDHC1_ROOT_SRC 191 | |
| 205 | +#define IMX7D_USDHC1_ROOT_CG 192 | |
| 206 | +#define IMX7D_USDHC1_ROOT_DIV 193 | |
| 207 | +#define IMX7D_USDHC2_ROOT_CLK 194 | |
| 208 | +#define IMX7D_USDHC2_ROOT_SRC 195 | |
| 209 | +#define IMX7D_USDHC2_ROOT_CG 196 | |
| 210 | +#define IMX7D_USDHC2_ROOT_DIV 197 | |
| 211 | +#define IMX7D_USDHC3_ROOT_CLK 198 | |
| 212 | +#define IMX7D_USDHC3_ROOT_SRC 199 | |
| 213 | +#define IMX7D_USDHC3_ROOT_CG 200 | |
| 214 | +#define IMX7D_USDHC3_ROOT_DIV 201 | |
| 215 | +#define IMX7D_CAN1_ROOT_CLK 202 | |
| 216 | +#define IMX7D_CAN1_ROOT_SRC 203 | |
| 217 | +#define IMX7D_CAN1_ROOT_CG 204 | |
| 218 | +#define IMX7D_CAN1_ROOT_DIV 205 | |
| 219 | +#define IMX7D_CAN2_ROOT_CLK 206 | |
| 220 | +#define IMX7D_CAN2_ROOT_SRC 207 | |
| 221 | +#define IMX7D_CAN2_ROOT_CG 208 | |
| 222 | +#define IMX7D_CAN2_ROOT_DIV 209 | |
| 223 | +#define IMX7D_I2C1_ROOT_CLK 210 | |
| 224 | +#define IMX7D_I2C1_ROOT_SRC 211 | |
| 225 | +#define IMX7D_I2C1_ROOT_CG 212 | |
| 226 | +#define IMX7D_I2C1_ROOT_DIV 213 | |
| 227 | +#define IMX7D_I2C2_ROOT_CLK 214 | |
| 228 | +#define IMX7D_I2C2_ROOT_SRC 215 | |
| 229 | +#define IMX7D_I2C2_ROOT_CG 216 | |
| 230 | +#define IMX7D_I2C2_ROOT_DIV 217 | |
| 231 | +#define IMX7D_I2C3_ROOT_CLK 218 | |
| 232 | +#define IMX7D_I2C3_ROOT_SRC 219 | |
| 233 | +#define IMX7D_I2C3_ROOT_CG 220 | |
| 234 | +#define IMX7D_I2C3_ROOT_DIV 221 | |
| 235 | +#define IMX7D_I2C4_ROOT_CLK 222 | |
| 236 | +#define IMX7D_I2C4_ROOT_SRC 223 | |
| 237 | +#define IMX7D_I2C4_ROOT_CG 224 | |
| 238 | +#define IMX7D_I2C4_ROOT_DIV 225 | |
| 239 | +#define IMX7D_UART1_ROOT_CLK 226 | |
| 240 | +#define IMX7D_UART1_ROOT_SRC 227 | |
| 241 | +#define IMX7D_UART1_ROOT_CG 228 | |
| 242 | +#define IMX7D_UART1_ROOT_DIV 229 | |
| 243 | +#define IMX7D_UART2_ROOT_CLK 230 | |
| 244 | +#define IMX7D_UART2_ROOT_SRC 231 | |
| 245 | +#define IMX7D_UART2_ROOT_CG 232 | |
| 246 | +#define IMX7D_UART2_ROOT_DIV 233 | |
| 247 | +#define IMX7D_UART3_ROOT_CLK 234 | |
| 248 | +#define IMX7D_UART3_ROOT_SRC 235 | |
| 249 | +#define IMX7D_UART3_ROOT_CG 236 | |
| 250 | +#define IMX7D_UART3_ROOT_DIV 237 | |
| 251 | +#define IMX7D_UART4_ROOT_CLK 238 | |
| 252 | +#define IMX7D_UART4_ROOT_SRC 239 | |
| 253 | +#define IMX7D_UART4_ROOT_CG 240 | |
| 254 | +#define IMX7D_UART4_ROOT_DIV 241 | |
| 255 | +#define IMX7D_UART5_ROOT_CLK 242 | |
| 256 | +#define IMX7D_UART5_ROOT_SRC 243 | |
| 257 | +#define IMX7D_UART5_ROOT_CG 244 | |
| 258 | +#define IMX7D_UART5_ROOT_DIV 245 | |
| 259 | +#define IMX7D_UART6_ROOT_CLK 246 | |
| 260 | +#define IMX7D_UART6_ROOT_SRC 247 | |
| 261 | +#define IMX7D_UART6_ROOT_CG 248 | |
| 262 | +#define IMX7D_UART6_ROOT_DIV 249 | |
| 263 | +#define IMX7D_UART7_ROOT_CLK 250 | |
| 264 | +#define IMX7D_UART7_ROOT_SRC 251 | |
| 265 | +#define IMX7D_UART7_ROOT_CG 252 | |
| 266 | +#define IMX7D_UART7_ROOT_DIV 253 | |
| 267 | +#define IMX7D_ECSPI1_ROOT_CLK 254 | |
| 268 | +#define IMX7D_ECSPI1_ROOT_SRC 255 | |
| 269 | +#define IMX7D_ECSPI1_ROOT_CG 256 | |
| 270 | +#define IMX7D_ECSPI1_ROOT_DIV 257 | |
| 271 | +#define IMX7D_ECSPI2_ROOT_CLK 258 | |
| 272 | +#define IMX7D_ECSPI2_ROOT_SRC 259 | |
| 273 | +#define IMX7D_ECSPI2_ROOT_CG 260 | |
| 274 | +#define IMX7D_ECSPI2_ROOT_DIV 261 | |
| 275 | +#define IMX7D_ECSPI3_ROOT_CLK 262 | |
| 276 | +#define IMX7D_ECSPI3_ROOT_SRC 263 | |
| 277 | +#define IMX7D_ECSPI3_ROOT_CG 264 | |
| 278 | +#define IMX7D_ECSPI3_ROOT_DIV 265 | |
| 279 | +#define IMX7D_ECSPI4_ROOT_CLK 266 | |
| 280 | +#define IMX7D_ECSPI4_ROOT_SRC 267 | |
| 281 | +#define IMX7D_ECSPI4_ROOT_CG 268 | |
| 282 | +#define IMX7D_ECSPI4_ROOT_DIV 269 | |
| 283 | +#define IMX7D_PWM1_ROOT_CLK 270 | |
| 284 | +#define IMX7D_PWM1_ROOT_SRC 271 | |
| 285 | +#define IMX7D_PWM1_ROOT_CG 272 | |
| 286 | +#define IMX7D_PWM1_ROOT_DIV 273 | |
| 287 | +#define IMX7D_PWM2_ROOT_CLK 274 | |
| 288 | +#define IMX7D_PWM2_ROOT_SRC 275 | |
| 289 | +#define IMX7D_PWM2_ROOT_CG 276 | |
| 290 | +#define IMX7D_PWM2_ROOT_DIV 277 | |
| 291 | +#define IMX7D_PWM3_ROOT_CLK 278 | |
| 292 | +#define IMX7D_PWM3_ROOT_SRC 279 | |
| 293 | +#define IMX7D_PWM3_ROOT_CG 280 | |
| 294 | +#define IMX7D_PWM3_ROOT_DIV 281 | |
| 295 | +#define IMX7D_PWM4_ROOT_CLK 282 | |
| 296 | +#define IMX7D_PWM4_ROOT_SRC 283 | |
| 297 | +#define IMX7D_PWM4_ROOT_CG 284 | |
| 298 | +#define IMX7D_PWM4_ROOT_DIV 285 | |
| 299 | +#define IMX7D_FLEXTIMER1_ROOT_CLK 286 | |
| 300 | +#define IMX7D_FLEXTIMER1_ROOT_SRC 287 | |
| 301 | +#define IMX7D_FLEXTIMER1_ROOT_CG 288 | |
| 302 | +#define IMX7D_FLEXTIMER1_ROOT_DIV 289 | |
| 303 | +#define IMX7D_FLEXTIMER2_ROOT_CLK 290 | |
| 304 | +#define IMX7D_FLEXTIMER2_ROOT_SRC 291 | |
| 305 | +#define IMX7D_FLEXTIMER2_ROOT_CG 292 | |
| 306 | +#define IMX7D_FLEXTIMER2_ROOT_DIV 293 | |
| 307 | +#define IMX7D_SIM1_ROOT_CLK 294 | |
| 308 | +#define IMX7D_SIM1_ROOT_SRC 295 | |
| 309 | +#define IMX7D_SIM1_ROOT_CG 296 | |
| 310 | +#define IMX7D_SIM1_ROOT_DIV 297 | |
| 311 | +#define IMX7D_SIM2_ROOT_CLK 298 | |
| 312 | +#define IMX7D_SIM2_ROOT_SRC 299 | |
| 313 | +#define IMX7D_SIM2_ROOT_CG 300 | |
| 314 | +#define IMX7D_SIM2_ROOT_DIV 301 | |
| 315 | +#define IMX7D_GPT1_ROOT_CLK 302 | |
| 316 | +#define IMX7D_GPT1_ROOT_SRC 303 | |
| 317 | +#define IMX7D_GPT1_ROOT_CG 304 | |
| 318 | +#define IMX7D_GPT1_ROOT_DIV 305 | |
| 319 | +#define IMX7D_GPT2_ROOT_CLK 306 | |
| 320 | +#define IMX7D_GPT2_ROOT_SRC 307 | |
| 321 | +#define IMX7D_GPT2_ROOT_CG 308 | |
| 322 | +#define IMX7D_GPT2_ROOT_DIV 309 | |
| 323 | +#define IMX7D_GPT3_ROOT_CLK 310 | |
| 324 | +#define IMX7D_GPT3_ROOT_SRC 311 | |
| 325 | +#define IMX7D_GPT3_ROOT_CG 312 | |
| 326 | +#define IMX7D_GPT3_ROOT_DIV 313 | |
| 327 | +#define IMX7D_GPT4_ROOT_CLK 314 | |
| 328 | +#define IMX7D_GPT4_ROOT_SRC 315 | |
| 329 | +#define IMX7D_GPT4_ROOT_CG 316 | |
| 330 | +#define IMX7D_GPT4_ROOT_DIV 317 | |
| 331 | +#define IMX7D_TRACE_ROOT_CLK 318 | |
| 332 | +#define IMX7D_TRACE_ROOT_SRC 319 | |
| 333 | +#define IMX7D_TRACE_ROOT_CG 320 | |
| 334 | +#define IMX7D_TRACE_ROOT_DIV 321 | |
| 335 | +#define IMX7D_WDOG1_ROOT_CLK 322 | |
| 336 | +#define IMX7D_WDOG_ROOT_SRC 323 | |
| 337 | +#define IMX7D_WDOG_ROOT_CG 324 | |
| 338 | +#define IMX7D_WDOG_ROOT_DIV 325 | |
| 339 | +#define IMX7D_CSI_MCLK_ROOT_CLK 326 | |
| 340 | +#define IMX7D_CSI_MCLK_ROOT_SRC 327 | |
| 341 | +#define IMX7D_CSI_MCLK_ROOT_CG 328 | |
| 342 | +#define IMX7D_CSI_MCLK_ROOT_DIV 329 | |
| 343 | +#define IMX7D_AUDIO_MCLK_ROOT_CLK 330 | |
| 344 | +#define IMX7D_AUDIO_MCLK_ROOT_SRC 331 | |
| 345 | +#define IMX7D_AUDIO_MCLK_ROOT_CG 332 | |
| 346 | +#define IMX7D_AUDIO_MCLK_ROOT_DIV 333 | |
| 347 | +#define IMX7D_WRCLK_ROOT_CLK 334 | |
| 348 | +#define IMX7D_WRCLK_ROOT_SRC 335 | |
| 349 | +#define IMX7D_WRCLK_ROOT_CG 336 | |
| 350 | +#define IMX7D_WRCLK_ROOT_DIV 337 | |
| 351 | +#define IMX7D_CLKO1_ROOT_SRC 338 | |
| 352 | +#define IMX7D_CLKO1_ROOT_CG 339 | |
| 353 | +#define IMX7D_CLKO1_ROOT_DIV 340 | |
| 354 | +#define IMX7D_CLKO2_ROOT_SRC 341 | |
| 355 | +#define IMX7D_CLKO2_ROOT_CG 342 | |
| 356 | +#define IMX7D_CLKO2_ROOT_DIV 343 | |
| 357 | +#define IMX7D_MAIN_AXI_ROOT_PRE_DIV 344 | |
| 358 | +#define IMX7D_DISP_AXI_ROOT_PRE_DIV 345 | |
| 359 | +#define IMX7D_ENET_AXI_ROOT_PRE_DIV 346 | |
| 360 | +#define IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV 347 | |
| 361 | +#define IMX7D_AHB_CHANNEL_ROOT_PRE_DIV 348 | |
| 362 | +#define IMX7D_USB_HSIC_ROOT_PRE_DIV 349 | |
| 363 | +#define IMX7D_PCIE_CTRL_ROOT_PRE_DIV 350 | |
| 364 | +#define IMX7D_PCIE_PHY_ROOT_PRE_DIV 351 | |
| 365 | +#define IMX7D_EPDC_PIXEL_ROOT_PRE_DIV 352 | |
| 366 | +#define IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV 353 | |
| 367 | +#define IMX7D_MIPI_DSI_ROOT_PRE_DIV 354 | |
| 368 | +#define IMX7D_MIPI_CSI_ROOT_PRE_DIV 355 | |
| 369 | +#define IMX7D_MIPI_DPHY_ROOT_PRE_DIV 356 | |
| 370 | +#define IMX7D_SAI1_ROOT_PRE_DIV 357 | |
| 371 | +#define IMX7D_SAI2_ROOT_PRE_DIV 358 | |
| 372 | +#define IMX7D_SAI3_ROOT_PRE_DIV 359 | |
| 373 | +#define IMX7D_SPDIF_ROOT_PRE_DIV 360 | |
| 374 | +#define IMX7D_ENET1_REF_ROOT_PRE_DIV 361 | |
| 375 | +#define IMX7D_ENET1_TIME_ROOT_PRE_DIV 362 | |
| 376 | +#define IMX7D_ENET2_REF_ROOT_PRE_DIV 363 | |
| 377 | +#define IMX7D_ENET2_TIME_ROOT_PRE_DIV 364 | |
| 378 | +#define IMX7D_ENET_PHY_REF_ROOT_PRE_DIV 365 | |
| 379 | +#define IMX7D_EIM_ROOT_PRE_DIV 366 | |
| 380 | +#define IMX7D_NAND_ROOT_PRE_DIV 367 | |
| 381 | +#define IMX7D_QSPI_ROOT_PRE_DIV 368 | |
| 382 | +#define IMX7D_USDHC1_ROOT_PRE_DIV 369 | |
| 383 | +#define IMX7D_USDHC2_ROOT_PRE_DIV 370 | |
| 384 | +#define IMX7D_USDHC3_ROOT_PRE_DIV 371 | |
| 385 | +#define IMX7D_CAN1_ROOT_PRE_DIV 372 | |
| 386 | +#define IMX7D_CAN2_ROOT_PRE_DIV 373 | |
| 387 | +#define IMX7D_I2C1_ROOT_PRE_DIV 374 | |
| 388 | +#define IMX7D_I2C2_ROOT_PRE_DIV 375 | |
| 389 | +#define IMX7D_I2C3_ROOT_PRE_DIV 376 | |
| 390 | +#define IMX7D_I2C4_ROOT_PRE_DIV 377 | |
| 391 | +#define IMX7D_UART1_ROOT_PRE_DIV 378 | |
| 392 | +#define IMX7D_UART2_ROOT_PRE_DIV 379 | |
| 393 | +#define IMX7D_UART3_ROOT_PRE_DIV 380 | |
| 394 | +#define IMX7D_UART4_ROOT_PRE_DIV 381 | |
| 395 | +#define IMX7D_UART5_ROOT_PRE_DIV 382 | |
| 396 | +#define IMX7D_UART6_ROOT_PRE_DIV 383 | |
| 397 | +#define IMX7D_UART7_ROOT_PRE_DIV 384 | |
| 398 | +#define IMX7D_ECSPI1_ROOT_PRE_DIV 385 | |
| 399 | +#define IMX7D_ECSPI2_ROOT_PRE_DIV 386 | |
| 400 | +#define IMX7D_ECSPI3_ROOT_PRE_DIV 387 | |
| 401 | +#define IMX7D_ECSPI4_ROOT_PRE_DIV 388 | |
| 402 | +#define IMX7D_PWM1_ROOT_PRE_DIV 389 | |
| 403 | +#define IMX7D_PWM2_ROOT_PRE_DIV 390 | |
| 404 | +#define IMX7D_PWM3_ROOT_PRE_DIV 391 | |
| 405 | +#define IMX7D_PWM4_ROOT_PRE_DIV 392 | |
| 406 | +#define IMX7D_FLEXTIMER1_ROOT_PRE_DIV 393 | |
| 407 | +#define IMX7D_FLEXTIMER2_ROOT_PRE_DIV 394 | |
| 408 | +#define IMX7D_SIM1_ROOT_PRE_DIV 395 | |
| 409 | +#define IMX7D_SIM2_ROOT_PRE_DIV 396 | |
| 410 | +#define IMX7D_GPT1_ROOT_PRE_DIV 397 | |
| 411 | +#define IMX7D_GPT2_ROOT_PRE_DIV 398 | |
| 412 | +#define IMX7D_GPT3_ROOT_PRE_DIV 399 | |
| 413 | +#define IMX7D_GPT4_ROOT_PRE_DIV 400 | |
| 414 | +#define IMX7D_TRACE_ROOT_PRE_DIV 401 | |
| 415 | +#define IMX7D_WDOG_ROOT_PRE_DIV 402 | |
| 416 | +#define IMX7D_CSI_MCLK_ROOT_PRE_DIV 403 | |
| 417 | +#define IMX7D_AUDIO_MCLK_ROOT_PRE_DIV 404 | |
| 418 | +#define IMX7D_WRCLK_ROOT_PRE_DIV 405 | |
| 419 | +#define IMX7D_CLKO1_ROOT_PRE_DIV 406 | |
| 420 | +#define IMX7D_CLKO2_ROOT_PRE_DIV 407 | |
| 421 | +#define IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV 408 | |
| 422 | +#define IMX7D_DRAM_ALT_ROOT_PRE_DIV 409 | |
| 423 | +#define IMX7D_LVDS1_IN_CLK 410 | |
| 424 | +#define IMX7D_LVDS1_OUT_SEL 411 | |
| 425 | +#define IMX7D_LVDS1_OUT_CLK 412 | |
| 426 | +#define IMX7D_CLK_DUMMY 413 | |
| 427 | +#define IMX7D_GPT_3M_CLK 414 | |
| 428 | +#define IMX7D_OCRAM_CLK 415 | |
| 429 | +#define IMX7D_OCRAM_S_CLK 416 | |
| 430 | +#define IMX7D_WDOG2_ROOT_CLK 417 | |
| 431 | +#define IMX7D_WDOG3_ROOT_CLK 418 | |
| 432 | +#define IMX7D_WDOG4_ROOT_CLK 419 | |
| 433 | +#define IMX7D_SDMA_CORE_CLK 420 | |
| 434 | +#define IMX7D_USB1_MAIN_480M_CLK 421 | |
| 435 | +#define IMX7D_USB_CTRL_CLK 422 | |
| 436 | +#define IMX7D_USB_PHY1_CLK 423 | |
| 437 | +#define IMX7D_USB_PHY2_CLK 424 | |
| 438 | +#define IMX7D_IPG_ROOT_CLK 425 | |
| 439 | +#define IMX7D_SAI1_IPG_CLK 426 | |
| 440 | +#define IMX7D_SAI2_IPG_CLK 427 | |
| 441 | +#define IMX7D_SAI3_IPG_CLK 428 | |
| 442 | +#define IMX7D_PLL_AUDIO_TEST_DIV 429 | |
| 443 | +#define IMX7D_PLL_AUDIO_POST_DIV 430 | |
| 444 | +#define IMX7D_PLL_VIDEO_TEST_DIV 431 | |
| 445 | +#define IMX7D_PLL_VIDEO_POST_DIV 432 | |
| 446 | +#define IMX7D_MU_ROOT_CLK 433 | |
| 447 | +#define IMX7D_SEMA4_HS_ROOT_CLK 434 | |
| 448 | +#define IMX7D_PLL_DRAM_TEST_DIV 435 | |
| 449 | +#define IMX7D_CLK_END 436 | |
| 450 | +#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ | |
| @@ -193,6 +193,7 @@ · 192 unmodified lines | ||
| 193 | 193 | #define VF610_PLL6_BYPASS 180 |
| 194 | 194 | #define VF610_PLL7_BYPASS 181 |
| 195 | 195 | #define VF610_CLK_SNVS 182 |
| 196 | −#define VF610_CLK_END 183 | |
| 196 | +#define VF610_CLK_DAP 183 | |
| 197 | +#define VF610_CLK_END 184 | |
| 197 | 198 | |
| 198 | 199 | #endif /* __DT_BINDINGS_CLOCK_VF610_H */ |
| @@ -0,0 +1,170 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2014 Linaro Ltd. | |
| 3 | + * Copyright (C) 2014 ZTE Corporation. | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License version 2 as | |
| 7 | + * published by the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#ifndef __DT_BINDINGS_CLOCK_ZX296702_H | |
| 11 | +#define __DT_BINDINGS_CLOCK_ZX296702_H | |
| 12 | + | |
| 13 | +#define ZX296702_OSC 0 | |
| 14 | +#define ZX296702_PLL_A9 1 | |
| 15 | +#define ZX296702_PLL_A9_350M 2 | |
| 16 | +#define ZX296702_PLL_MAC_1000M 3 | |
| 17 | +#define ZX296702_PLL_MAC_333M 4 | |
| 18 | +#define ZX296702_PLL_MM0_1188M 5 | |
| 19 | +#define ZX296702_PLL_MM0_396M 6 | |
| 20 | +#define ZX296702_PLL_MM0_198M 7 | |
| 21 | +#define ZX296702_PLL_MM1_108M 8 | |
| 22 | +#define ZX296702_PLL_MM1_72M 9 | |
| 23 | +#define ZX296702_PLL_MM1_54M 10 | |
| 24 | +#define ZX296702_PLL_LSP_104M 11 | |
| 25 | +#define ZX296702_PLL_LSP_26M 12 | |
| 26 | +#define ZX296702_PLL_AUDIO_294M912 13 | |
| 27 | +#define ZX296702_PLL_DDR_266M 14 | |
| 28 | +#define ZX296702_CLK_148M5 15 | |
| 29 | +#define ZX296702_MATRIX_ACLK 16 | |
| 30 | +#define ZX296702_MAIN_HCLK 17 | |
| 31 | +#define ZX296702_MAIN_PCLK 18 | |
| 32 | +#define ZX296702_CLK_500 19 | |
| 33 | +#define ZX296702_CLK_250 20 | |
| 34 | +#define ZX296702_CLK_125 21 | |
| 35 | +#define ZX296702_CLK_74M25 22 | |
| 36 | +#define ZX296702_A9_WCLK 23 | |
| 37 | +#define ZX296702_A9_AS1_ACLK_MUX 24 | |
| 38 | +#define ZX296702_A9_TRACE_CLKIN_MUX 25 | |
| 39 | +#define ZX296702_A9_AS1_ACLK_DIV 26 | |
| 40 | +#define ZX296702_CLK_2 27 | |
| 41 | +#define ZX296702_CLK_27 28 | |
| 42 | +#define ZX296702_DECPPU_ACLK_MUX 29 | |
| 43 | +#define ZX296702_PPU_ACLK_MUX 30 | |
| 44 | +#define ZX296702_MALI400_ACLK_MUX 31 | |
| 45 | +#define ZX296702_VOU_ACLK_MUX 32 | |
| 46 | +#define ZX296702_VOU_MAIN_WCLK_MUX 33 | |
| 47 | +#define ZX296702_VOU_AUX_WCLK_MUX 34 | |
| 48 | +#define ZX296702_VOU_SCALER_WCLK_MUX 35 | |
| 49 | +#define ZX296702_R2D_ACLK_MUX 36 | |
| 50 | +#define ZX296702_R2D_WCLK_MUX 37 | |
| 51 | +#define ZX296702_CLK_50 38 | |
| 52 | +#define ZX296702_CLK_25 39 | |
| 53 | +#define ZX296702_CLK_12 40 | |
| 54 | +#define ZX296702_CLK_16M384 41 | |
| 55 | +#define ZX296702_CLK_32K768 42 | |
| 56 | +#define ZX296702_SEC_WCLK_DIV 43 | |
| 57 | +#define ZX296702_DDR_WCLK_MUX 44 | |
| 58 | +#define ZX296702_NAND_WCLK_MUX 45 | |
| 59 | +#define ZX296702_LSP_26_WCLK_MUX 46 | |
| 60 | +#define ZX296702_A9_AS0_ACLK 47 | |
| 61 | +#define ZX296702_A9_AS1_ACLK 48 | |
| 62 | +#define ZX296702_A9_TRACE_CLKIN 49 | |
| 63 | +#define ZX296702_DECPPU_AXI_M_ACLK 50 | |
| 64 | +#define ZX296702_DECPPU_AHB_S_HCLK 51 | |
| 65 | +#define ZX296702_PPU_AXI_M_ACLK 52 | |
| 66 | +#define ZX296702_PPU_AHB_S_HCLK 53 | |
| 67 | +#define ZX296702_VOU_AXI_M_ACLK 54 | |
| 68 | +#define ZX296702_VOU_APB_PCLK 55 | |
| 69 | +#define ZX296702_VOU_MAIN_CHANNEL_WCLK 56 | |
| 70 | +#define ZX296702_VOU_AUX_CHANNEL_WCLK 57 | |
| 71 | +#define ZX296702_VOU_HDMI_OSCLK_CEC 58 | |
| 72 | +#define ZX296702_VOU_SCALER_WCLK 59 | |
| 73 | +#define ZX296702_MALI400_AXI_M_ACLK 60 | |
| 74 | +#define ZX296702_MALI400_APB_PCLK 61 | |
| 75 | +#define ZX296702_R2D_WCLK 62 | |
| 76 | +#define ZX296702_R2D_AXI_M_ACLK 63 | |
| 77 | +#define ZX296702_R2D_AHB_HCLK 64 | |
| 78 | +#define ZX296702_DDR3_AXI_S0_ACLK 65 | |
| 79 | +#define ZX296702_DDR3_APB_PCLK 66 | |
| 80 | +#define ZX296702_DDR3_WCLK 67 | |
| 81 | +#define ZX296702_USB20_0_AHB_HCLK 68 | |
| 82 | +#define ZX296702_USB20_0_EXTREFCLK 69 | |
| 83 | +#define ZX296702_USB20_1_AHB_HCLK 70 | |
| 84 | +#define ZX296702_USB20_1_EXTREFCLK 71 | |
| 85 | +#define ZX296702_USB20_2_AHB_HCLK 72 | |
| 86 | +#define ZX296702_USB20_2_EXTREFCLK 73 | |
| 87 | +#define ZX296702_GMAC_AXI_M_ACLK 74 | |
| 88 | +#define ZX296702_GMAC_APB_PCLK 75 | |
| 89 | +#define ZX296702_GMAC_125_CLKIN 76 | |
| 90 | +#define ZX296702_GMAC_RMII_CLKIN 77 | |
| 91 | +#define ZX296702_GMAC_25M_CLK 78 | |
| 92 | +#define ZX296702_NANDFLASH_AHB_HCLK 79 | |
| 93 | +#define ZX296702_NANDFLASH_WCLK 80 | |
| 94 | +#define ZX296702_LSP0_APB_PCLK 81 | |
| 95 | +#define ZX296702_LSP0_AHB_HCLK 82 | |
| 96 | +#define ZX296702_LSP0_26M_WCLK 83 | |
| 97 | +#define ZX296702_LSP0_104M_WCLK 84 | |
| 98 | +#define ZX296702_LSP0_16M384_WCLK 85 | |
| 99 | +#define ZX296702_LSP1_APB_PCLK 86 | |
| 100 | +#define ZX296702_LSP1_26M_WCLK 87 | |
| 101 | +#define ZX296702_LSP1_104M_WCLK 88 | |
| 102 | +#define ZX296702_LSP1_32K_CLK 89 | |
| 103 | +#define ZX296702_AON_HCLK 90 | |
| 104 | +#define ZX296702_SYS_CTRL_PCLK 91 | |
| 105 | +#define ZX296702_DMA_PCLK 92 | |
| 106 | +#define ZX296702_DMA_ACLK 93 | |
| 107 | +#define ZX296702_SEC_HCLK 94 | |
| 108 | +#define ZX296702_AES_WCLK 95 | |
| 109 | +#define ZX296702_DES_WCLK 96 | |
| 110 | +#define ZX296702_IRAM_ACLK 97 | |
| 111 | +#define ZX296702_IROM_ACLK 98 | |
| 112 | +#define ZX296702_BOOT_CTRL_HCLK 99 | |
| 113 | +#define ZX296702_EFUSE_CLK_30 100 | |
| 114 | +#define ZX296702_VOU_MAIN_CHANNEL_DIV 101 | |
| 115 | +#define ZX296702_VOU_AUX_CHANNEL_DIV 102 | |
| 116 | +#define ZX296702_VOU_TV_ENC_HD_DIV 103 | |
| 117 | +#define ZX296702_VOU_TV_ENC_SD_DIV 104 | |
| 118 | +#define ZX296702_VL0_MUX 105 | |
| 119 | +#define ZX296702_VL1_MUX 106 | |
| 120 | +#define ZX296702_VL2_MUX 107 | |
| 121 | +#define ZX296702_GL0_MUX 108 | |
| 122 | +#define ZX296702_GL1_MUX 109 | |
| 123 | +#define ZX296702_GL2_MUX 110 | |
| 124 | +#define ZX296702_WB_MUX 111 | |
| 125 | +#define ZX296702_HDMI_MUX 112 | |
| 126 | +#define ZX296702_VOU_TV_ENC_HD_MUX 113 | |
| 127 | +#define ZX296702_VOU_TV_ENC_SD_MUX 114 | |
| 128 | +#define ZX296702_VL0_CLK 115 | |
| 129 | +#define ZX296702_VL1_CLK 116 | |
| 130 | +#define ZX296702_VL2_CLK 117 | |
| 131 | +#define ZX296702_GL0_CLK 118 | |
| 132 | +#define ZX296702_GL1_CLK 119 | |
| 133 | +#define ZX296702_GL2_CLK 120 | |
| 134 | +#define ZX296702_WB_CLK 121 | |
| 135 | +#define ZX296702_CL_CLK 122 | |
| 136 | +#define ZX296702_MAIN_MIX_CLK 123 | |
| 137 | +#define ZX296702_AUX_MIX_CLK 124 | |
| 138 | +#define ZX296702_HDMI_CLK 125 | |
| 139 | +#define ZX296702_VOU_TV_ENC_HD_DAC_CLK 126 | |
| 140 | +#define ZX296702_VOU_TV_ENC_SD_DAC_CLK 127 | |
| 141 | +#define ZX296702_A9_PERIPHCLK 128 | |
| 142 | +#define ZX296702_TOPCLK_END 129 | |
| 143 | + | |
| 144 | +#define ZX296702_SDMMC1_WCLK_MUX 0 | |
| 145 | +#define ZX296702_SDMMC1_WCLK_DIV 1 | |
| 146 | +#define ZX296702_SDMMC1_WCLK 2 | |
| 147 | +#define ZX296702_SDMMC1_PCLK 3 | |
| 148 | +#define ZX296702_SPDIF0_WCLK_MUX 4 | |
| 149 | +#define ZX296702_SPDIF0_WCLK 5 | |
| 150 | +#define ZX296702_SPDIF0_PCLK 6 | |
| 151 | +#define ZX296702_SPDIF0_DIV 7 | |
| 152 | +#define ZX296702_I2S0_WCLK_MUX 8 | |
| 153 | +#define ZX296702_I2S0_WCLK 9 | |
| 154 | +#define ZX296702_I2S0_PCLK 10 | |
| 155 | +#define ZX296702_I2S0_DIV 11 | |
| 156 | +#define ZX296702_LSP0CLK_END 12 | |
| 157 | + | |
| 158 | +#define ZX296702_UART0_WCLK_MUX 0 | |
| 159 | +#define ZX296702_UART0_WCLK 1 | |
| 160 | +#define ZX296702_UART0_PCLK 2 | |
| 161 | +#define ZX296702_UART1_WCLK_MUX 3 | |
| 162 | +#define ZX296702_UART1_WCLK 4 | |
| 163 | +#define ZX296702_UART1_PCLK 5 | |
| 164 | +#define ZX296702_SDMMC0_WCLK_MUX 6 | |
| 165 | +#define ZX296702_SDMMC0_WCLK_DIV 7 | |
| 166 | +#define ZX296702_SDMMC0_WCLK 8 | |
| 167 | +#define ZX296702_SDMMC0_PCLK 9 | |
| 168 | +#define ZX296702_LSP1CLK_END 10 | |
| 169 | + | |
| 170 | +#endif /* __DT_BINDINGS_CLOCK_ZX296702_H */ | |
| @@ -0,0 +1,88 @@ | ||
| 1 | +/* | |
| 2 | + * Broadcom BCM63xx Processor Monitor Bus shared routines (SMP and reset) | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015, Broadcom Corporation | |
| 5 | + * Author: Florian Fainelli <f.fainelli@gmail.com> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or | |
| 8 | + * modify it under the terms of the GNU General Public License as | |
| 9 | + * published by the Free Software Foundation version 2. | |
| 10 | + * | |
| 11 | + * This program is distributed "as is" WITHOUT ANY WARRANTY of any | |
| 12 | + * kind, whether express or implied; without even the implied warranty | |
| 13 | + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + * GNU General Public License for more details. | |
| 15 | + */ | |
| 16 | +#ifndef __BCM63XX_PMB_H | |
| 17 | +#define __BCM63XX_PMB_H | |
| 18 | + | |
| 19 | +#include <linux/io.h> | |
| 20 | +#include <linux/types.h> | |
| 21 | +#include <linux/delay.h> | |
| 22 | +#include <linux/err.h> | |
| 23 | + | |
| 24 | +/* PMB Master controller register */ | |
| 25 | +#define PMB_CTRL 0x00 | |
| 26 | +#define PMC_PMBM_START (1 << 31) | |
| 27 | +#define PMC_PMBM_TIMEOUT (1 << 30) | |
| 28 | +#define PMC_PMBM_SLAVE_ERR (1 << 29) | |
| 29 | +#define PMC_PMBM_BUSY (1 << 28) | |
| 30 | +#define PMC_PMBM_READ (0 << 20) | |
| 31 | +#define PMC_PMBM_WRITE (1 << 20) | |
| 32 | +#define PMB_WR_DATA 0x04 | |
| 33 | +#define PMB_TIMEOUT 0x08 | |
| 34 | +#define PMB_RD_DATA 0x0C | |
| 35 | + | |
| 36 | +#define PMB_BUS_ID_SHIFT 8 | |
| 37 | + | |
| 38 | +/* Perform the low-level PMB master operation, shared between reads and | |
| 39 | + * writes. | |
| 40 | + */ | |
| 41 | +static inline int __bpcm_do_op(void __iomem *master, unsigned int addr, | |
| 42 | + u32 off, u32 op) | |
| 43 | +{ | |
| 44 | + unsigned int timeout = 1000; | |
| 45 | + u32 cmd; | |
| 46 | + | |
| 47 | + cmd = (PMC_PMBM_START | op | (addr & 0xff) << 12 | off); | |
| 48 | + writel(cmd, master + PMB_CTRL); | |
| 49 | + do { | |
| 50 | + cmd = readl(master + PMB_CTRL); | |
| 51 | + if (!(cmd & PMC_PMBM_START)) | |
| 52 | + return 0; | |
| 53 | + | |
| 54 | + if (cmd & PMC_PMBM_SLAVE_ERR) | |
| 55 | + return -EIO; | |
| 56 | + | |
| 57 | + if (cmd & PMC_PMBM_TIMEOUT) | |
| 58 | + return -ETIMEDOUT; | |
| 59 | + | |
| 60 | + udelay(1); | |
| 61 | + } while (timeout-- > 0); | |
| 62 | + | |
| 63 | + return -ETIMEDOUT; | |
| 64 | +} | |
| 65 | + | |
| 66 | +static inline int bpcm_rd(void __iomem *master, unsigned int addr, | |
| 67 | + u32 off, u32 *val) | |
| 68 | +{ | |
| 69 | + int ret = 0; | |
| 70 | + | |
| 71 | + ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_READ); | |
| 72 | + *val = readl(master + PMB_RD_DATA); | |
| 73 | + | |
| 74 | + return ret; | |
| 75 | +} | |
| 76 | + | |
| 77 | +static inline int bpcm_wr(void __iomem *master, unsigned int addr, | |
| 78 | + u32 off, u32 val) | |
| 79 | +{ | |
| 80 | + int ret = 0; | |
| 81 | + | |
| 82 | + writel(val, master + PMB_WR_DATA); | |
| 83 | + ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_WRITE); | |
| 84 | + | |
| 85 | + return ret; | |
| 86 | +} | |
| 87 | + | |
| 88 | +#endif /* __BCM63XX_PMB_H */ | |
| @@ -0,0 +1,37 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2015 Linaro Ltd. | |
| 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 __SOC_IMX_REVISION_H__ | |
| 10 | +#define __SOC_IMX_REVISION_H__ | |
| 11 | + | |
| 12 | +#define IMX_CHIP_REVISION_1_0 0x10 | |
| 13 | +#define IMX_CHIP_REVISION_1_1 0x11 | |
| 14 | +#define IMX_CHIP_REVISION_1_2 0x12 | |
| 15 | +#define IMX_CHIP_REVISION_1_3 0x13 | |
| 16 | +#define IMX_CHIP_REVISION_1_4 0x14 | |
| 17 | +#define IMX_CHIP_REVISION_1_5 0x15 | |
| 18 | +#define IMX_CHIP_REVISION_2_0 0x20 | |
| 19 | +#define IMX_CHIP_REVISION_2_1 0x21 | |
| 20 | +#define IMX_CHIP_REVISION_2_2 0x22 | |
| 21 | +#define IMX_CHIP_REVISION_2_3 0x23 | |
| 22 | +#define IMX_CHIP_REVISION_3_0 0x30 | |
| 23 | +#define IMX_CHIP_REVISION_3_1 0x31 | |
| 24 | +#define IMX_CHIP_REVISION_3_2 0x32 | |
| 25 | +#define IMX_CHIP_REVISION_3_3 0x33 | |
| 26 | +#define IMX_CHIP_REVISION_UNKNOWN 0xff | |
| 27 | + | |
| 28 | +int mx27_revision(void); | |
| 29 | +int mx31_revision(void); | |
| 30 | +int mx35_revision(void); | |
| 31 | +int mx51_revision(void); | |
| 32 | +int mx53_revision(void); | |
| 33 | + | |
| 34 | +unsigned int imx_get_soc_revision(void); | |
| 35 | +void imx_print_silicon_rev(const char *cpu, int srev); | |
| 36 | + | |
| 37 | +#endif /* __SOC_IMX_REVISION_H__ */ | |
| @@ -0,0 +1,26 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2015 Linaro Ltd. | |
| 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 __SOC_IMX_TIMER_H__ | |
| 10 | +#define __SOC_IMX_TIMER_H__ | |
| 11 | + | |
| 12 | +enum imx_gpt_type { | |
| 13 | + GPT_TYPE_IMX1, /* i.MX1 */ | |
| 14 | + GPT_TYPE_IMX21, /* i.MX21/27 */ | |
| 15 | + GPT_TYPE_IMX31, /* i.MX31/35/25/37/51/6Q */ | |
| 16 | + GPT_TYPE_IMX6DL, /* i.MX6DL/SX/SL */ | |
| 17 | +}; | |
| 18 | + | |
| 19 | +/* | |
| 20 | + * This is a stop-gap solution for clock drivers like imx1/imx21 which call | |
| 21 | + * mxc_timer_init() to initialize timer for non-DT boot. It can be removed | |
| 22 | + * when these legacy non-DT support is converted or dropped. | |
| 23 | + */ | |
| 24 | +void mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type); | |
| 25 | + | |
| 26 | +#endif /* __SOC_IMX_TIMER_H__ */ | |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | struct clk; |
| 27 | 27 | struct reset_control; |
| 28 | 28 | |
| 29 | −void tegra_pmc_restart(enum reboot_mode mode, const char *cmd); | |
| 30 | − | |
| 31 | 29 | #ifdef CONFIG_PM_SLEEP |
| 32 | 30 | enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void); |
| 33 | 31 | void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); |
| @@ -331,6 +331,9 @@ · 330 unmodified lines | ||
| 331 | 331 | * Extra serial register definitions for the internal UARTs |
| 332 | 332 | * in TI OMAP processors. |
| 333 | 333 | */ |
| 334 | +#define OMAP1_UART1_BASE 0xfffb0000 | |
| 335 | +#define OMAP1_UART2_BASE 0xfffb0800 | |
| 336 | +#define OMAP1_UART3_BASE 0xfffb9800 | |
| 334 | 337 | #define UART_OMAP_MDR1 0x08 /* Mode definition register */ |
| 335 | 338 | #define UART_OMAP_MDR2 0x09 /* Mode definition register 2 */ |
| 336 | 339 | #define UART_OMAP_SCR 0x10 /* Supplementary control register */ |