Commit 6e207b88 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm-soc-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc

Pull ARM SoC updates from Olof Johansson:
 "A few SoC (code) changes have queued up this cycle, mostly for minor
  changes and some refactoring and cleanup of legacy platforms. This
  branch also contains a few of the fixes that weren't sent in by the
  end of the release (all fairly minor).

   - Adding an additional maintainer for the TEE subsystem (Sumit Garg)

   - Quite a significant modernization of the IXP4xx platforms by Linus
     Walleij, revisiting with a new PCI host driver/binding, removing
     legacy mach/* include dependencies and moving platform
     detection/config to drivers/soc. Also some updates/cleanup of
     platform data.

   - Core power domain support for Tegra platforms, and some
     improvements in build test coverage by adding stubs for compile
     test targets.

   - A handful of updates to i.MX platforms, adding legacy (non-PSCI)
     SMP support on i.MX7D, SoC ID setup for i.MX50, removal of platform
     data and board fixups for iMX6/7.

  ... and a few smaller changes and fixes for Samsung, OMAP, Allwinner,
  Rockchip"

* tag 'arm-soc-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (53 commits)
  MAINTAINERS: Add myself as TEE subsystem reviewer
  ixp4xx: fix spelling mistake in Kconfig "Devce" -> "Device"
  hw_random: ixp4xx: Add OF support
  hw_random: ixp4xx: Add DT bindings
  hw_random: ixp4xx: Turn into a module
  hw_random: ixp4xx: Use SPDX license tag
  hw_random: ixp4xx: enable compile-testing
  pata: ixp4xx: split platform data to its own header
  soc: ixp4xx: move cpu detection to linux/soc/ixp4xx/cpu.h
  PCI: ixp4xx: Add a new driver for IXP4xx
  PCI: ixp4xx: Add device tree bindings for IXP4xx
  ARM/ixp4xx: Make NEED_MACH_IO_H optional
  ARM/ixp4xx: Move the virtual IObases
  MAINTAINERS: ARM/MStar/Sigmastar SoCs: Add a link to the MStar tree
  ARM: debug: add UART early console support for MSTAR SoCs
  ARM: dts: ux500: Fix LED probing
  ARM: imx: add smp support for imx7d
  ARM: imx6q: drop of_platform_default_populate() from init_machine
  arm64: dts: rockchip: Update RK3399 PCI host bridge window to 32-bit address memory
  soc/tegra: fuse: Fix Tegra234-only builds
  ...
parents b6fd9e25 42accadb
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pci/intel,ixp4xx-pci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Intel IXP4xx PCI controller
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
description: PCI host controller found in the Intel IXP4xx SoC series.
allOf:
- $ref: /schemas/pci/pci-bus.yaml#
properties:
compatible:
items:
- enum:
- intel,ixp42x-pci
- intel,ixp43x-pci
description: The two supported variants are ixp42x and ixp43x,
though more variants may exist.
reg:
items:
- description: IXP4xx-specific registers
interrupts:
items:
- description: Main PCI interrupt
- description: PCI DMA interrupt 1
- description: PCI DMA interrupt 2
ranges:
maxItems: 2
description: Typically one memory range of 64MB and one IO
space range of 64KB.
dma-ranges:
maxItems: 1
description: The DMA range tells the PCI host which addresses
the RAM is at. It can map only 64MB so if the RAM is bigger
than 64MB the DMA access has to be restricted to these
addresses.
"#interrupt-cells": true
interrupt-map: true
interrupt-map-mask:
items:
- const: 0xf800
- const: 0
- const: 0
- const: 7
required:
- compatible
- reg
- dma-ranges
- "#interrupt-cells"
- interrupt-map
- interrupt-map-mask
unevaluatedProperties: false
examples:
- |
pci@c0000000 {
compatible = "intel,ixp43x-pci";
reg = <0xc0000000 0x1000>;
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
bus-range = <0x00 0xff>;
ranges =
<0x02000000 0 0x48000000 0x48000000 0 0x04000000>,
<0x01000000 0 0x00000000 0x4c000000 0 0x00010000>;
dma-ranges =
<0x02000000 0 0x00000000 0x00000000 0 0x04000000>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xf800 0 0 7>;
interrupt-map =
<0x0800 0 0 1 &gpio0 11 3>, /* INT A on slot 1 is irq 11 */
<0x0800 0 0 2 &gpio0 10 3>, /* INT B on slot 1 is irq 10 */
<0x0800 0 0 3 &gpio0 9 3>, /* INT C on slot 1 is irq 9 */
<0x0800 0 0 4 &gpio0 8 3>, /* INT D on slot 1 is irq 8 */
<0x1000 0 0 1 &gpio0 10 3>, /* INT A on slot 2 is irq 10 */
<0x1000 0 0 2 &gpio0 9 3>, /* INT B on slot 2 is irq 9 */
<0x1000 0 0 3 &gpio0 8 3>, /* INT C on slot 2 is irq 8 */
<0x1000 0 0 4 &gpio0 11 3>, /* INT D on slot 2 is irq 11 */
<0x1800 0 0 1 &gpio0 9 3>, /* INT A on slot 3 is irq 9 */
<0x1800 0 0 2 &gpio0 8 3>, /* INT B on slot 3 is irq 8 */
<0x1800 0 0 3 &gpio0 11 3>, /* INT C on slot 3 is irq 11 */
<0x1800 0 0 4 &gpio0 10 3>; /* INT D on slot 3 is irq 10 */
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/rng/intel,ixp46x-rng.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Intel IXP46x RNG bindings
description: |
The Intel IXP46x has a random number generator at a fixed physical
location in memory. Each read is guaranteed to provide a unique
32 bit random number.
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
properties:
compatible:
const: intel,ixp46x-rng
reg:
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
rng@70002100 {
compatible = "intel,ixp46x-rng";
reg = <0x70002100 4>;
};
...@@ -2210,6 +2210,7 @@ M: Daniel Palmer <daniel@thingy.jp> ...@@ -2210,6 +2210,7 @@ M: Daniel Palmer <daniel@thingy.jp>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained S: Maintained
W: http://linux-chenxing.org/ W: http://linux-chenxing.org/
T: git git://github.com/linux-chenxing/linux.git
F: Documentation/devicetree/bindings/arm/mstar/* F: Documentation/devicetree/bindings/arm/mstar/*
F: Documentation/devicetree/bindings/clock/mstar,msc313-mpll.yaml F: Documentation/devicetree/bindings/clock/mstar,msc313-mpll.yaml
F: Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml F: Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml
...@@ -2479,9 +2480,12 @@ F: drivers/*/*/*s3c24* ...@@ -2479,9 +2480,12 @@ F: drivers/*/*/*s3c24*
F: drivers/*/*s3c24* F: drivers/*/*s3c24*
F: drivers/*/*s3c64xx* F: drivers/*/*s3c64xx*
F: drivers/*/*s5pv210* F: drivers/*/*s5pv210*
F: drivers/clocksource/samsung_pwm_timer.c
F: drivers/memory/samsung/ F: drivers/memory/samsung/
F: drivers/pwm/pwm-samsung.c
F: drivers/soc/samsung/ F: drivers/soc/samsung/
F: drivers/tty/serial/samsung* F: drivers/tty/serial/samsung*
F: include/clocksource/samsung_pwm.h
F: include/linux/platform_data/*s3c* F: include/linux/platform_data/*s3c*
F: include/linux/serial_s3c.h F: include/linux/serial_s3c.h
F: include/linux/soc/samsung/ F: include/linux/soc/samsung/
...@@ -9381,6 +9385,7 @@ F: include/linux/soc/ixp4xx/qmgr.h ...@@ -9381,6 +9385,7 @@ F: include/linux/soc/ixp4xx/qmgr.h
INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
M: Deepak Saxena <dsaxena@plexity.net> M: Deepak Saxena <dsaxena@plexity.net>
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/display/intel,ixp46x-rng.yaml
F: drivers/char/hw_random/ixp4xx-rng.c F: drivers/char/hw_random/ixp4xx-rng.c
INTEL KEEM BAY DRM DRIVER INTEL KEEM BAY DRM DRIVER
...@@ -13510,12 +13515,6 @@ L: linux-omap@vger.kernel.org ...@@ -13510,12 +13515,6 @@ L: linux-omap@vger.kernel.org
S: Maintained S: Maintained
F: arch/arm/mach-omap2/omap_hwmod*data* F: arch/arm/mach-omap2/omap_hwmod*data*
OMAP HWMOD DATA FOR OMAP4-BASED DEVICES
M: Benoît Cousson <bcousson@baylibre.com>
L: linux-omap@vger.kernel.org
S: Maintained
F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c
OMAP HWMOD SUPPORT OMAP HWMOD SUPPORT
M: Benoît Cousson <bcousson@baylibre.com> M: Benoît Cousson <bcousson@baylibre.com>
M: Paul Walmsley <paul@pwsan.com> M: Paul Walmsley <paul@pwsan.com>
...@@ -14179,6 +14178,12 @@ S: Maintained ...@@ -14179,6 +14178,12 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
F: drivers/pci/controller/dwc/pcie-fu740.c F: drivers/pci/controller/dwc/pcie-fu740.c
PCI DRIVER FOR INTEL IXP4XX
M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained
F: Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml
F: drivers/pci/controller/pci-ixp4xx.c
PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
M: Jonathan Derrick <jonathan.derrick@intel.com> M: Jonathan Derrick <jonathan.derrick@intel.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
...@@ -18126,6 +18131,7 @@ F: include/media/i2c/tw9910.h ...@@ -18126,6 +18131,7 @@ F: include/media/i2c/tw9910.h
TEE SUBSYSTEM TEE SUBSYSTEM
M: Jens Wiklander <jens.wiklander@linaro.org> M: Jens Wiklander <jens.wiklander@linaro.org>
R: Sumit Garg <sumit.garg@linaro.org>
L: op-tee@lists.trustedfirmware.org L: op-tee@lists.trustedfirmware.org
S: Maintained S: Maintained
F: Documentation/staging/tee.rst F: Documentation/staging/tee.rst
......
...@@ -394,7 +394,8 @@ config ARCH_IXP4XX ...@@ -394,7 +394,8 @@ config ARCH_IXP4XX
select HAVE_PCI select HAVE_PCI
select IXP4XX_IRQ select IXP4XX_IRQ
select IXP4XX_TIMER select IXP4XX_TIMER
select NEED_MACH_IO_H # With the new PCI driver this is not needed
select NEED_MACH_IO_H if PCI_IXP4XX_LEGACY
select USB_EHCI_BIG_ENDIAN_DESC select USB_EHCI_BIG_ENDIAN_DESC
select USB_EHCI_BIG_ENDIAN_MMIO select USB_EHCI_BIG_ENDIAN_MMIO
help help
......
...@@ -609,6 +609,14 @@ choice ...@@ -609,6 +609,14 @@ choice
when u-boot hands over to the kernel, the system when u-boot hands over to the kernel, the system
silently crashes, with no serial output at all. silently crashes, with no serial output at all.
config DEBUG_MSTARV7_PMUART
bool "Kernel low-level debugging messages via MSTARV7 PM UART"
depends on ARCH_MSTARV7
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
for MSTAR ARMv7-based platforms on PM UART.
config DEBUG_MT6589_UART0 config DEBUG_MT6589_UART0
bool "Mediatek mt6589 UART0" bool "Mediatek mt6589 UART0"
depends on ARCH_MEDIATEK depends on ARCH_MEDIATEK
...@@ -1607,6 +1615,7 @@ config DEBUG_UART_PHYS ...@@ -1607,6 +1615,7 @@ config DEBUG_UART_PHYS
default 0x18000400 if DEBUG_BCM_HR2 default 0x18000400 if DEBUG_BCM_HR2
default 0x18023000 if DEBUG_BCM_IPROC_UART3 default 0x18023000 if DEBUG_BCM_IPROC_UART3
default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1 default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
default 0x1f221000 if DEBUG_MSTARV7_PMUART
default 0x20001000 if DEBUG_HIP01_UART default 0x20001000 if DEBUG_HIP01_UART
default 0x20060000 if DEBUG_RK29_UART0 default 0x20060000 if DEBUG_RK29_UART0
default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
...@@ -1724,6 +1733,7 @@ config DEBUG_UART_VIRT ...@@ -1724,6 +1733,7 @@ config DEBUG_UART_VIRT
default 0xf0100000 if DEBUG_DIGICOLOR_UA0 default 0xf0100000 if DEBUG_DIGICOLOR_UA0
default 0xf01fb000 if DEBUG_NOMADIK_UART default 0xf01fb000 if DEBUG_NOMADIK_UART
default 0xf0201000 if DEBUG_BCM2835 || DEBUG_BCM2836 default 0xf0201000 if DEBUG_BCM2835 || DEBUG_BCM2836
default 0xf0221000 if DEBUG_MSTARV7_PMUART
default 0xf1000300 if DEBUG_BCM_5301X default 0xf1000300 if DEBUG_BCM_5301X
default 0xf1000400 if DEBUG_BCM_HR2 default 0xf1000400 if DEBUG_BCM_HR2
default 0xf1002000 if DEBUG_MT8127_UART0 default 0xf1002000 if DEBUG_MT8127_UART0
...@@ -1805,8 +1815,8 @@ config DEBUG_UART_VIRT ...@@ -1805,8 +1815,8 @@ config DEBUG_UART_VIRT
default 0xfedc0000 if DEBUG_EP93XX default 0xfedc0000 if DEBUG_EP93XX
default 0xfee003f8 if DEBUG_FOOTBRIDGE_COM1 default 0xfee003f8 if DEBUG_FOOTBRIDGE_COM1
default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN default 0xfec00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN default 0xfec00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
default 0xfef36000 if DEBUG_HIGHBANK_UART default 0xfef36000 if DEBUG_HIGHBANK_UART
default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1 default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
default 0xfefb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2 default 0xfefb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
...@@ -1829,6 +1839,7 @@ config DEBUG_UART_8250_SHIFT ...@@ -1829,6 +1839,7 @@ config DEBUG_UART_8250_SHIFT
default 0 if DEBUG_FOOTBRIDGE_COM1 || ARCH_IOP32X || DEBUG_BCM_5301X || \ default 0 if DEBUG_FOOTBRIDGE_COM1 || ARCH_IOP32X || DEBUG_BCM_5301X || \
DEBUG_BCM_HR2 || DEBUG_OMAP7XXUART1 || DEBUG_OMAP7XXUART2 || \ DEBUG_BCM_HR2 || DEBUG_OMAP7XXUART1 || DEBUG_OMAP7XXUART2 || \
DEBUG_OMAP7XXUART3 DEBUG_OMAP7XXUART3
default 3 if DEBUG_MSTARV7_PMUART
default 2 default 2
config DEBUG_UART_8250_WORD config DEBUG_UART_8250_WORD
......
...@@ -17,17 +17,13 @@ / { ...@@ -17,17 +17,13 @@ / {
* VCP1, VCP2 * VCP1, VCP2
* MLB * MLB
* ISS * ISS
* USB3, USB4 * USB3
*/ */
&usb3_tm { &usb3_tm {
status = "disabled"; status = "disabled";
}; };
&usb4_tm {
status = "disabled";
};
&atl_tm { &atl_tm {
status = "disabled"; status = "disabled";
}; };
...@@ -4129,28 +4129,6 @@ usb3: usb@10000 { ...@@ -4129,28 +4129,6 @@ usb3: usb@10000 {
}; };
}; };
usb4_tm: target-module@140000 { /* 0x48940000, ap 75 3c.0 */
compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x140000 0x4>,
<0x140010 0x4>;
reg-names = "rev", "sysc";
ti,sysc-mask = <SYSC_OMAP4_DMADISABLE>;
ti,sysc-midle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
/* Domains (P, C): l3init_pwrdm, l3init_clkdm */
clocks = <&l3init_clkctrl DRA7_L3INIT_USB_OTG_SS4_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x140000 0x20000>;
};
target-module@170000 { /* 0x48970000, ap 21 0a.0 */ target-module@170000 { /* 0x48970000, ap 21 0a.0 */
compatible = "ti,sysc-omap4", "ti,sysc"; compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x170010 0x4>; reg = <0x170010 0x4>;
......
...@@ -11,7 +11,3 @@ ...@@ -11,7 +11,3 @@
&rtctarget { &rtctarget {
status = "disabled"; status = "disabled";
}; };
&usb4_tm {
status = "disabled";
};
...@@ -108,7 +108,3 @@ &pcie1_ep { ...@@ -108,7 +108,3 @@ &pcie1_ep {
&pcie2_rc { &pcie2_rc {
compatible = "ti,dra726-pcie-rc", "ti,dra7-pcie"; compatible = "ti,dra726-pcie-rc", "ti,dra7-pcie";
}; };
&usb4_tm {
status = "disabled";
};
...@@ -49,49 +49,6 @@ dsp2_system: dsp_system@41500000 { ...@@ -49,49 +49,6 @@ dsp2_system: dsp_system@41500000 {
reg = <0x41500000 0x100>; reg = <0x41500000 0x100>;
}; };
target-module@48940000 {
compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x48940000 0x4>,
<0x48940010 0x4>;
reg-names = "rev", "sysc";
ti,sysc-mask = <SYSC_OMAP4_DMADISABLE>;
ti,sysc-midle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
clocks = <&l3init_clkctrl DRA7_L3INIT_USB_OTG_SS4_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x48940000 0x20000>;
omap_dwc3_4: omap_dwc3_4@0 {
compatible = "ti,dwc3";
reg = <0 0x10000>;
interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <1>;
utmi-mode = <2>;
ranges;
status = "disabled";
usb4: usb@10000 {
compatible = "snps,dwc3";
reg = <0x10000 0x17000>;
interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "peripheral",
"host",
"otg";
maximum-speed = "high-speed";
dr_mode = "otg";
};
};
};
target-module@41501000 { target-module@41501000 {
compatible = "ti,sysc-omap2", "ti,sysc"; compatible = "ti,sysc-omap2", "ti,sysc";
...@@ -224,3 +181,52 @@ &pcie1_ep { ...@@ -224,3 +181,52 @@ &pcie1_ep {
&pcie2_rc { &pcie2_rc {
compatible = "ti,dra746-pcie-rc", "ti,dra7-pcie"; compatible = "ti,dra746-pcie-rc", "ti,dra7-pcie";
}; };
&l4_per3 {
segment@0 {
usb4_tm: target-module@140000 { /* 0x48940000, ap 75 3c.0 */
compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x140000 0x4>,
<0x140010 0x4>;
reg-names = "rev", "sysc";
ti,sysc-mask = <SYSC_OMAP4_DMADISABLE>;
ti,sysc-midle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
/* Domains (P, C): l3init_pwrdm, l3init_clkdm */
clocks = <&l3init_clkctrl DRA7_L3INIT_USB_OTG_SS4_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x140000 0x20000>;
omap_dwc3_4: omap_dwc3_4@0 {
compatible = "ti,dwc3";
reg = <0 0x10000>;
interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <1>;
utmi-mode = <2>;
ranges;
status = "disabled";
usb4: usb@10000 {
compatible = "snps,dwc3";
reg = <0x10000 0x17000>;
interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "peripheral",
"host",
"otg";
maximum-speed = "high-speed";
dr_mode = "otg";
};
};
};
};
};
...@@ -250,7 +250,7 @@ nand@0 { ...@@ -250,7 +250,7 @@ nand@0 {
nand-ecc-step-size = <512>; nand-ecc-step-size = <512>;
nand-bus-width = <8>; nand-bus-width = <8>;
/* efs2 partition is secured */ /* efs2 partition is secured */
secure-regions = <0x500000 0xb00000>; secure-regions = /bits/ 64 <0x500000 0xb00000>;
}; };
}; };
......
...@@ -250,8 +250,8 @@ nand@0 { ...@@ -250,8 +250,8 @@ nand@0 {
nand-ecc-step-size = <512>; nand-ecc-step-size = <512>;
nand-bus-width = <8>; nand-bus-width = <8>;
/* ico and efs2 partitions are secured */ /* ico and efs2 partitions are secured */
secure-regions = <0x500000 0x500000 secure-regions = /bits/ 64 <0x500000 0x500000
0xa00000 0xb00000>; 0xa00000 0xb00000>;
}; };
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/leds/common.h>
#include "ste-href-family-pinctrl.dtsi" #include "ste-href-family-pinctrl.dtsi"
/ { / {
...@@ -64,17 +65,20 @@ chan@0 { ...@@ -64,17 +65,20 @@ chan@0 {
reg = <0>; reg = <0>;
led-cur = /bits/ 8 <0x2f>; led-cur = /bits/ 8 <0x2f>;
max-cur = /bits/ 8 <0x5f>; max-cur = /bits/ 8 <0x5f>;
color = <LED_COLOR_ID_BLUE>;
linux,default-trigger = "heartbeat"; linux,default-trigger = "heartbeat";
}; };
chan@1 { chan@1 {
reg = <1>; reg = <1>;
led-cur = /bits/ 8 <0x2f>; led-cur = /bits/ 8 <0x2f>;
max-cur = /bits/ 8 <0x5f>; max-cur = /bits/ 8 <0x5f>;
color = <LED_COLOR_ID_BLUE>;
}; };
chan@2 { chan@2 {
reg = <2>; reg = <2>;
led-cur = /bits/ 8 <0x2f>; led-cur = /bits/ 8 <0x2f>;
max-cur = /bits/ 8 <0x5f>; max-cur = /bits/ 8 <0x5f>;
color = <LED_COLOR_ID_BLUE>;
}; };
}; };
lp5521@34 { lp5521@34 {
...@@ -88,16 +92,19 @@ chan@0 { ...@@ -88,16 +92,19 @@ chan@0 {
reg = <0>; reg = <0>;
led-cur = /bits/ 8 <0x2f>; led-cur = /bits/ 8 <0x2f>;
max-cur = /bits/ 8 <0x5f>; max-cur = /bits/ 8 <0x5f>;
color = <LED_COLOR_ID_BLUE>;
}; };
chan@1 { chan@1 {
reg = <1>; reg = <1>;
led-cur = /bits/ 8 <0x2f>; led-cur = /bits/ 8 <0x2f>;
max-cur = /bits/ 8 <0x5f>; max-cur = /bits/ 8 <0x5f>;
color = <LED_COLOR_ID_BLUE>;
}; };
chan@2 { chan@2 {
reg = <2>; reg = <2>;
led-cur = /bits/ 8 <0x2f>; led-cur = /bits/ 8 <0x2f>;
max-cur = /bits/ 8 <0x5f>; max-cur = /bits/ 8 <0x5f>;
color = <LED_COLOR_ID_BLUE>;
}; };
}; };
bh1780@29 { bh1780@29 {
......
...@@ -85,7 +85,7 @@ &emac { ...@@ -85,7 +85,7 @@ &emac {
pinctrl-0 = <&emac_rgmii_pins>; pinctrl-0 = <&emac_rgmii_pins>;
phy-supply = <&reg_gmac_3v3>; phy-supply = <&reg_gmac_3v3>;
phy-handle = <&ext_rgmii_phy>; phy-handle = <&ext_rgmii_phy>;
phy-mode = "rgmii"; phy-mode = "rgmii-id";
status = "okay"; status = "okay";
}; };
......
...@@ -55,6 +55,7 @@ void __init exynos_sysram_init(void) ...@@ -55,6 +55,7 @@ void __init exynos_sysram_init(void)
sysram_base_addr = of_iomap(node, 0); sysram_base_addr = of_iomap(node, 0);
sysram_base_phys = of_translate_address(node, sysram_base_phys = of_translate_address(node,
of_get_address(node, 0, NULL, NULL)); of_get_address(node, 0, NULL, NULL));
of_node_put(node);
break; break;
} }
...@@ -62,6 +63,7 @@ void __init exynos_sysram_init(void) ...@@ -62,6 +63,7 @@ void __init exynos_sysram_init(void)
if (!of_device_is_available(node)) if (!of_device_is_available(node))
continue; continue;
sysram_ns_base_addr = of_iomap(node, 0); sysram_ns_base_addr = of_iomap(node, 0);
of_node_put(node);
break; break;
} }
} }
......
...@@ -35,7 +35,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o ...@@ -35,7 +35,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
obj-$(CONFIG_HAVE_IMX_SRC) += src.o obj-$(CONFIG_HAVE_IMX_SRC) += src.o
ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),) ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_IMX7D_CA7)$(CONFIG_SOC_LS1021A),)
AFLAGS_headsmp.o :=-Wa,-march=armv7-a AFLAGS_headsmp.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SMP) += headsmp.o platsmp.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
......
...@@ -68,11 +68,13 @@ void imx_set_cpu_arg(int cpu, u32 arg); ...@@ -68,11 +68,13 @@ void imx_set_cpu_arg(int cpu, u32 arg);
void v7_secondary_startup(void); void v7_secondary_startup(void);
void imx_scu_map_io(void); void imx_scu_map_io(void);
void imx_smp_prepare(void); void imx_smp_prepare(void);
void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn);
#else #else
static inline void imx_scu_map_io(void) {} static inline void imx_scu_map_io(void) {}
static inline void imx_smp_prepare(void) {} static inline void imx_smp_prepare(void) {}
#endif #endif
void imx_src_init(void); void imx_src_init(void);
void imx7_src_init(void);
void imx_gpc_pre_suspend(bool arm_power_off); void imx_gpc_pre_suspend(bool arm_power_off);
void imx_gpc_post_resume(void); void imx_gpc_post_resume(void);
void imx_gpc_mask_all(void); void imx_gpc_mask_all(void);
...@@ -131,6 +133,7 @@ static inline void imx_init_l2cache(void) {} ...@@ -131,6 +133,7 @@ static inline void imx_init_l2cache(void) {}
#endif #endif
extern const struct smp_operations imx_smp_ops; extern const struct smp_operations imx_smp_ops;
extern const struct smp_operations imx7_smp_ops;
extern const struct smp_operations ls1021a_smp_ops; extern const struct smp_operations ls1021a_smp_ops;
#endif #endif
...@@ -21,6 +21,15 @@ diag_reg_offset: ...@@ -21,6 +21,15 @@ diag_reg_offset:
ENTRY(v7_secondary_startup) ENTRY(v7_secondary_startup)
ARM_BE8(setend be) @ go BE8 if entered LE ARM_BE8(setend be) @ go BE8 if entered LE
mrc p15, 0, r0, c0, c0, 0
lsl r0, r0, #16
lsr r0, r0, #20
/* 0xc07 is cortex A7's ID */
mov r1, #0xc00
orr r1, #0x7
cmp r0, r1
beq secondary_startup
set_diag_reg set_diag_reg
b secondary_startup b secondary_startup
ENDPROC(v7_secondary_startup) ENDPROC(v7_secondary_startup)
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
#include "common.h" #include "common.h"
#include "hardware.h"
/* /*
* platform-specific code to shutdown a CPU * platform-specific code to shutdown a CPU
...@@ -40,5 +41,7 @@ int imx_cpu_kill(unsigned int cpu) ...@@ -40,5 +41,7 @@ int imx_cpu_kill(unsigned int cpu)
return 0; return 0;
imx_enable_cpu(cpu, false); imx_enable_cpu(cpu, false);
imx_set_cpu_arg(cpu, 0); imx_set_cpu_arg(cpu, 0);
if (cpu_is_imx7d())
imx_gpcv2_set_core1_pdn_pup_by_software(true);
return 1; return 1;
} }
...@@ -9,6 +9,12 @@ ...@@ -9,6 +9,12 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include "common.h" #include "common.h"
#include "hardware.h"
static void __init imx50_init_early(void)
{
mxc_set_cpu_type(MXC_CPU_MX50);
}
static const char * const imx50_dt_board_compat[] __initconst = { static const char * const imx50_dt_board_compat[] __initconst = {
"fsl,imx50", "fsl,imx50",
...@@ -16,5 +22,6 @@ static const char * const imx50_dt_board_compat[] __initconst = { ...@@ -16,5 +22,6 @@ static const char * const imx50_dt_board_compat[] __initconst = {
}; };
DT_MACHINE_START(IMX50_DT, "Freescale i.MX50 (Device Tree Support)") DT_MACHINE_START(IMX50_DT, "Freescale i.MX50 (Device Tree Support)")
.init_early = imx50_init_early,
.dt_compat = imx50_dt_board_compat, .dt_compat = imx50_dt_board_compat,
MACHINE_END MACHINE_END
...@@ -40,27 +40,6 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev) ...@@ -40,27 +40,6 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
return 0; return 0;
} }
static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val)
{
phy_write(dev, 0x0d, device);
phy_write(dev, 0x0e, reg);
phy_write(dev, 0x0d, (1 << 14) | device);
phy_write(dev, 0x0e, val);
}
static int ksz9031rn_phy_fixup(struct phy_device *dev)
{
/*
* min rx data delay, max rx/tx clock delay,
* min rx/tx control delay
*/
mmd_write_reg(dev, 2, 4, 0);
mmd_write_reg(dev, 2, 5, 0);
mmd_write_reg(dev, 2, 8, 0x003ff);
return 0;
}
/* /*
* fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High * fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High
* as they are used for slots1-7 PERST# * as they are used for slots1-7 PERST#
...@@ -89,75 +68,11 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup); ...@@ -89,75 +68,11 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup);
static int ar8031_phy_fixup(struct phy_device *dev)
{
u16 val;
/* To enable AR8031 output a 125MHz clk from CLK_25M */
phy_write(dev, 0xd, 0x7);
phy_write(dev, 0xe, 0x8016);
phy_write(dev, 0xd, 0x4007);
val = phy_read(dev, 0xe);
val &= 0xffe3;
val |= 0x18;
phy_write(dev, 0xe, val);
/* introduce tx clock delay */
phy_write(dev, 0x1d, 0x5);
val = phy_read(dev, 0x1e);
val |= 0x0100;
phy_write(dev, 0x1e, val);
return 0;
}
#define PHY_ID_AR8031 0x004dd074
static int ar8035_phy_fixup(struct phy_device *dev)
{
u16 val;
/* Ar803x phy SmartEEE feature cause link status generates glitch,
* which cause ethernet link down/up issue, so disable SmartEEE
*/
phy_write(dev, 0xd, 0x3);
phy_write(dev, 0xe, 0x805d);
phy_write(dev, 0xd, 0x4003);
val = phy_read(dev, 0xe);
phy_write(dev, 0xe, val & ~(1 << 8));
/*
* Enable 125MHz clock from CLK_25M on the AR8031. This
* is fed in to the IMX6 on the ENET_REF_CLK (V22) pad.
* Also, introduce a tx clock delay.
*
* This is the same as is the AR8031 fixup.
*/
ar8031_phy_fixup(dev);
/*check phy power*/
val = phy_read(dev, 0x0);
if (val & BMCR_PDOWN)
phy_write(dev, 0x0, val & ~BMCR_PDOWN);
return 0;
}
#define PHY_ID_AR8035 0x004dd072
static void __init imx6q_enet_phy_init(void) static void __init imx6q_enet_phy_init(void)
{ {
if (IS_BUILTIN(CONFIG_PHYLIB)) { if (IS_BUILTIN(CONFIG_PHYLIB)) {
phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
ksz9021rn_phy_fixup); ksz9021rn_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
ksz9031rn_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffef,
ar8031_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef,
ar8035_phy_fixup);
} }
} }
...@@ -257,9 +172,6 @@ static void __init imx6q_init_machine(void) ...@@ -257,9 +172,6 @@ static void __init imx6q_init_machine(void)
imx_get_soc_revision()); imx_get_soc_revision());
imx6q_enet_phy_init(); imx6q_enet_phy_init();
of_platform_default_populate(NULL, NULL, NULL);
imx_anatop_init(); imx_anatop_init();
cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init(); cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init();
imx6q_1588_init(); imx6q_1588_init();
......
...@@ -15,31 +15,6 @@ ...@@ -15,31 +15,6 @@
#include "common.h" #include "common.h"
#include "cpuidle.h" #include "cpuidle.h"
static int ar8031_phy_fixup(struct phy_device *dev)
{
u16 val;
/* Set RGMII IO voltage to 1.8V */
phy_write(dev, 0x1d, 0x1f);
phy_write(dev, 0x1e, 0x8);
/* introduce tx clock delay */
phy_write(dev, 0x1d, 0x5);
val = phy_read(dev, 0x1e);
val |= 0x0100;
phy_write(dev, 0x1e, val);
return 0;
}
#define PHY_ID_AR8031 0x004dd074
static void __init imx6sx_enet_phy_init(void)
{
if (IS_BUILTIN(CONFIG_PHYLIB))
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
ar8031_phy_fixup);
}
static void __init imx6sx_enet_clk_sel(void) static void __init imx6sx_enet_clk_sel(void)
{ {
struct regmap *gpr; struct regmap *gpr;
...@@ -57,7 +32,6 @@ static void __init imx6sx_enet_clk_sel(void) ...@@ -57,7 +32,6 @@ static void __init imx6sx_enet_clk_sel(void)
static inline void imx6sx_enet_init(void) static inline void imx6sx_enet_init(void)
{ {
imx6sx_enet_phy_init();
imx6sx_enet_clk_sel(); imx6sx_enet_clk_sel();
} }
......
...@@ -14,25 +14,6 @@ ...@@ -14,25 +14,6 @@
#include "common.h" #include "common.h"
static int ar8031_phy_fixup(struct phy_device *dev)
{
u16 val;
/* Set RGMII IO voltage to 1.8V */
phy_write(dev, 0x1d, 0x1f);
phy_write(dev, 0x1e, 0x8);
/* disable phy AR8031 SmartEEE function. */
phy_write(dev, 0xd, 0x3);
phy_write(dev, 0xe, 0x805d);
phy_write(dev, 0xd, 0x4003);
val = phy_read(dev, 0xe);
val &= ~(0x1 << 8);
phy_write(dev, 0xe, val);
return 0;
}
static int bcm54220_phy_fixup(struct phy_device *dev) static int bcm54220_phy_fixup(struct phy_device *dev)
{ {
/* enable RXC skew select RGMII copper mode */ /* enable RXC skew select RGMII copper mode */
...@@ -44,14 +25,11 @@ static int bcm54220_phy_fixup(struct phy_device *dev) ...@@ -44,14 +25,11 @@ static int bcm54220_phy_fixup(struct phy_device *dev)
return 0; return 0;
} }
#define PHY_ID_AR8031 0x004dd074
#define PHY_ID_BCM54220 0x600d8589 #define PHY_ID_BCM54220 0x600d8589
static void __init imx7d_enet_phy_init(void) static void __init imx7d_enet_phy_init(void)
{ {
if (IS_BUILTIN(CONFIG_PHYLIB)) { if (IS_BUILTIN(CONFIG_PHYLIB)) {
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
ar8031_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff, phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff,
bcm54220_phy_fixup); bcm54220_phy_fixup);
} }
...@@ -91,7 +69,7 @@ static void __init imx7d_init_late(void) ...@@ -91,7 +69,7 @@ static void __init imx7d_init_late(void)
static void __init imx7d_init_irq(void) static void __init imx7d_init_irq(void)
{ {
imx_init_revision_from_anatop(); imx_init_revision_from_anatop();
imx_src_init(); imx7_src_init();
irqchip_init(); irqchip_init();
} }
...@@ -102,6 +80,7 @@ static const char *const imx7d_dt_compat[] __initconst = { ...@@ -102,6 +80,7 @@ static const char *const imx7d_dt_compat[] __initconst = {
}; };
DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)") DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)")
.smp = smp_ops(imx7_smp_ops),
.init_irq = imx7d_init_irq, .init_irq = imx7d_init_irq,
.init_machine = imx7d_init_machine, .init_machine = imx7d_init_machine,
.init_late = imx7d_init_late, .init_late = imx7d_init_late,
......
...@@ -92,6 +92,32 @@ const struct smp_operations imx_smp_ops __initconst = { ...@@ -92,6 +92,32 @@ const struct smp_operations imx_smp_ops __initconst = {
#endif #endif
}; };
/*
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
static void __init imx7_smp_init_cpus(void)
{
struct device_node *np;
int i, ncores = 0;
/* The iMX7D SCU does not report core count, get it from DT */
for_each_of_cpu_node(np)
ncores++;
for (i = ncores; i < NR_CPUS; i++)
set_cpu_possible(i, false);
}
const struct smp_operations imx7_smp_ops __initconst = {
.smp_init_cpus = imx7_smp_init_cpus,
.smp_boot_secondary = imx_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = imx_cpu_die,
.cpu_kill = imx_cpu_kill,
#endif
};
#define DCFG_CCSR_SCRATCHRW1 0x200 #define DCFG_CCSR_SCRATCHRW1 0x200
static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle) static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle)
......
...@@ -6,15 +6,19 @@ ...@@ -6,15 +6,19 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/reset-controller.h> #include <linux/reset-controller.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include "common.h" #include "common.h"
#include "hardware.h"
#define SRC_SCR 0x000 #define SRC_SCR 0x000
#define SRC_GPR1 0x020 #define SRC_GPR1_V1 0x020
#define SRC_GPR1_V2 0x074
#define SRC_GPR1(gpr_v2) ((gpr_v2) ? SRC_GPR1_V2 : SRC_GPR1_V1)
#define BP_SRC_SCR_WARM_RESET_ENABLE 0 #define BP_SRC_SCR_WARM_RESET_ENABLE 0
#define BP_SRC_SCR_SW_GPU_RST 1 #define BP_SRC_SCR_SW_GPU_RST 1
#define BP_SRC_SCR_SW_VPU_RST 2 #define BP_SRC_SCR_SW_VPU_RST 2
...@@ -23,9 +27,18 @@ ...@@ -23,9 +27,18 @@
#define BP_SRC_SCR_SW_IPU2_RST 12 #define BP_SRC_SCR_SW_IPU2_RST 12
#define BP_SRC_SCR_CORE1_RST 14 #define BP_SRC_SCR_CORE1_RST 14
#define BP_SRC_SCR_CORE1_ENABLE 22 #define BP_SRC_SCR_CORE1_ENABLE 22
/* below is for i.MX7D */
#define SRC_A7RCR1 0x008
#define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1
#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
#define GPC_PGC_C1 0x840
#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2
static void __iomem *src_base; static void __iomem *src_base;
static DEFINE_SPINLOCK(scr_lock); static DEFINE_SPINLOCK(scr_lock);
static bool gpr_v2;
static void __iomem *gpc_base;
static const int sw_reset_bits[5] = { static const int sw_reset_bits[5] = {
BP_SRC_SCR_SW_GPU_RST, BP_SRC_SCR_SW_GPU_RST,
...@@ -73,17 +86,64 @@ static struct reset_controller_dev imx_reset_controller = { ...@@ -73,17 +86,64 @@ static struct reset_controller_dev imx_reset_controller = {
.nr_resets = ARRAY_SIZE(sw_reset_bits), .nr_resets = ARRAY_SIZE(sw_reset_bits),
}; };
static void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset)
{
writel_relaxed(enable, gpc_base + offset);
}
/*
* The motivation for bringing up the second i.MX7D core inside the kernel
* is that legacy vendor bootloaders usually do not implement PSCI support.
* This is a significant blocker for systems in the field that are running old
* bootloader versions to upgrade to a modern mainline kernel version, as only
* one CPU of the i.MX7D would be brought up.
* Bring up the second i.MX7D core inside the kernel to make the migration
* path to mainline kernel easier for the existing iMX7D users.
*/
void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn)
{
u32 reg = pdn ? GPC_CPU_PGC_SW_PDN_REQ : GPC_CPU_PGC_SW_PUP_REQ;
u32 val, pup;
int ret;
imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1);
val = readl_relaxed(gpc_base + reg);
val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7;
writel_relaxed(val, gpc_base + reg);
ret = readl_relaxed_poll_timeout_atomic(gpc_base + reg, pup,
!(pup & BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7),
5, 1000000);
if (ret < 0) {
pr_err("i.MX7D: CORE1_A7 power up timeout\n");
val &= ~BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7;
writel_relaxed(val, gpc_base + reg);
}
imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1);
}
void imx_enable_cpu(int cpu, bool enable) void imx_enable_cpu(int cpu, bool enable)
{ {
u32 mask, val; u32 mask, val;
cpu = cpu_logical_map(cpu); cpu = cpu_logical_map(cpu);
mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
spin_lock(&scr_lock); spin_lock(&scr_lock);
val = readl_relaxed(src_base + SRC_SCR); if (gpr_v2) {
val = enable ? val | mask : val & ~mask; if (enable)
val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1); imx_gpcv2_set_core1_pdn_pup_by_software(false);
writel_relaxed(val, src_base + SRC_SCR);
mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1);
val = readl_relaxed(src_base + SRC_A7RCR1);
val = enable ? val | mask : val & ~mask;
writel_relaxed(val, src_base + SRC_A7RCR1);
} else {
mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
val = readl_relaxed(src_base + SRC_SCR);
val = enable ? val | mask : val & ~mask;
val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
writel_relaxed(val, src_base + SRC_SCR);
}
spin_unlock(&scr_lock); spin_unlock(&scr_lock);
} }
...@@ -91,19 +151,19 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) ...@@ -91,19 +151,19 @@ void imx_set_cpu_jump(int cpu, void *jump_addr)
{ {
cpu = cpu_logical_map(cpu); cpu = cpu_logical_map(cpu);
writel_relaxed(__pa_symbol(jump_addr), writel_relaxed(__pa_symbol(jump_addr),
src_base + SRC_GPR1 + cpu * 8); src_base + SRC_GPR1(gpr_v2) + cpu * 8);
} }
u32 imx_get_cpu_arg(int cpu) u32 imx_get_cpu_arg(int cpu)
{ {
cpu = cpu_logical_map(cpu); cpu = cpu_logical_map(cpu);
return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); return readl_relaxed(src_base + SRC_GPR1(gpr_v2) + cpu * 8 + 4);
} }
void imx_set_cpu_arg(int cpu, u32 arg) void imx_set_cpu_arg(int cpu, u32 arg)
{ {
cpu = cpu_logical_map(cpu); cpu = cpu_logical_map(cpu);
writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); writel_relaxed(arg, src_base + SRC_GPR1(gpr_v2) + cpu * 8 + 4);
} }
void __init imx_src_init(void) void __init imx_src_init(void)
...@@ -131,3 +191,26 @@ void __init imx_src_init(void) ...@@ -131,3 +191,26 @@ void __init imx_src_init(void)
writel_relaxed(val, src_base + SRC_SCR); writel_relaxed(val, src_base + SRC_SCR);
spin_unlock(&scr_lock); spin_unlock(&scr_lock);
} }
void __init imx7_src_init(void)
{
struct device_node *np;
gpr_v2 = true;
np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-src");
if (!np)
return;
src_base = of_iomap(np, 0);
if (!src_base)
return;
np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-gpc");
if (!np)
return;
gpc_base = of_iomap(np, 0);
if (!gpc_base)
return;
}
...@@ -28,11 +28,11 @@ ...@@ -28,11 +28,11 @@
* ^ * ^
* ^ * ^
* imx53_suspend code * imx53_suspend code
* PM_INFO structure(imx53_suspend_info) * PM_INFO structure(imx5_cpu_suspend_info)
* ======================== low address ======================= * ======================== low address =======================
*/ */
/* Offsets of members of struct imx53_suspend_info */ /* Offsets of members of struct imx5_cpu_suspend_info */
#define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 #define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0
#define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 #define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4
#define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 #define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8
......
...@@ -7,7 +7,7 @@ comment "IXP4xx Platforms" ...@@ -7,7 +7,7 @@ comment "IXP4xx Platforms"
config MACH_IXP4XX_OF config MACH_IXP4XX_OF
bool bool
prompt "Devce Tree IXP4xx boards" prompt "Device Tree IXP4xx boards"
default y default y
select ARM_APPENDED_DTB # Old Redboot bootloaders deployed select ARM_APPENDED_DTB # Old Redboot bootloaders deployed
select I2C select I2C
...@@ -20,7 +20,7 @@ config MACH_IXP4XX_OF ...@@ -20,7 +20,7 @@ config MACH_IXP4XX_OF
config MACH_NSLU2 config MACH_NSLU2
bool bool
prompt "Linksys NSLU2" prompt "Linksys NSLU2"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support Linksys's Say 'Y' here if you want your kernel to support Linksys's
NSLU2 NAS device. For more information on this platform, NSLU2 NAS device. For more information on this platform,
...@@ -28,7 +28,7 @@ config MACH_NSLU2 ...@@ -28,7 +28,7 @@ config MACH_NSLU2
config MACH_AVILA config MACH_AVILA
bool "Avila" bool "Avila"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support the Gateworks Say 'Y' here if you want your kernel to support the Gateworks
Avila Network Platform. For more information on this platform, Avila Network Platform. For more information on this platform,
...@@ -44,7 +44,7 @@ config MACH_LOFT ...@@ -44,7 +44,7 @@ config MACH_LOFT
config ARCH_ADI_COYOTE config ARCH_ADI_COYOTE
bool "Coyote" bool "Coyote"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support the ADI Say 'Y' here if you want your kernel to support the ADI
Engineering Coyote Gateway Reference Platform. For more Engineering Coyote Gateway Reference Platform. For more
...@@ -52,7 +52,7 @@ config ARCH_ADI_COYOTE ...@@ -52,7 +52,7 @@ config ARCH_ADI_COYOTE
config MACH_GATEWAY7001 config MACH_GATEWAY7001
bool "Gateway 7001" bool "Gateway 7001"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support Gateway's Say 'Y' here if you want your kernel to support Gateway's
7001 Access Point. For more information on this platform, 7001 Access Point. For more information on this platform,
...@@ -60,7 +60,7 @@ config MACH_GATEWAY7001 ...@@ -60,7 +60,7 @@ config MACH_GATEWAY7001
config MACH_WG302V2 config MACH_WG302V2
bool "Netgear WG302 v2 / WAG302 v2" bool "Netgear WG302 v2 / WAG302 v2"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support Netgear's Say 'Y' here if you want your kernel to support Netgear's
WG302 v2 or WAG302 v2 Access Points. For more information WG302 v2 or WAG302 v2 Access Points. For more information
...@@ -68,6 +68,7 @@ config MACH_WG302V2 ...@@ -68,6 +68,7 @@ config MACH_WG302V2
config ARCH_IXDP425 config ARCH_IXDP425
bool "IXDP425" bool "IXDP425"
depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support Intel's Say 'Y' here if you want your kernel to support Intel's
IXDP425 Development Platform (Also known as Richfield). IXDP425 Development Platform (Also known as Richfield).
...@@ -75,6 +76,7 @@ config ARCH_IXDP425 ...@@ -75,6 +76,7 @@ config ARCH_IXDP425
config MACH_IXDPG425 config MACH_IXDPG425
bool "IXDPG425" bool "IXDPG425"
depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support Intel's Say 'Y' here if you want your kernel to support Intel's
IXDPG425 Development Platform (Also known as Montajade). IXDPG425 Development Platform (Also known as Montajade).
...@@ -120,7 +122,7 @@ config ARCH_PRPMC1100 ...@@ -120,7 +122,7 @@ config ARCH_PRPMC1100
config MACH_NAS100D config MACH_NAS100D
bool bool
prompt "NAS100D" prompt "NAS100D"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support Iomega's Say 'Y' here if you want your kernel to support Iomega's
NAS 100d device. For more information on this platform, NAS 100d device. For more information on this platform,
...@@ -129,7 +131,7 @@ config MACH_NAS100D ...@@ -129,7 +131,7 @@ config MACH_NAS100D
config MACH_DSMG600 config MACH_DSMG600
bool bool
prompt "D-Link DSM-G600 RevA" prompt "D-Link DSM-G600 RevA"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support D-Link's Say 'Y' here if you want your kernel to support D-Link's
DSM-G600 RevA device. For more information on this platform, DSM-G600 RevA device. For more information on this platform,
...@@ -143,7 +145,7 @@ config ARCH_IXDP4XX ...@@ -143,7 +145,7 @@ config ARCH_IXDP4XX
config MACH_FSG config MACH_FSG
bool bool
prompt "Freecom FSG-3" prompt "Freecom FSG-3"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support Freecom's Say 'Y' here if you want your kernel to support Freecom's
FSG-3 device. For more information on this platform, FSG-3 device. For more information on this platform,
...@@ -152,7 +154,7 @@ config MACH_FSG ...@@ -152,7 +154,7 @@ config MACH_FSG
config MACH_ARCOM_VULCAN config MACH_ARCOM_VULCAN
bool bool
prompt "Arcom/Eurotech Vulcan" prompt "Arcom/Eurotech Vulcan"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support Arcom's Say 'Y' here if you want your kernel to support Arcom's
Vulcan board. Vulcan board.
...@@ -173,7 +175,7 @@ config CPU_IXP43X ...@@ -173,7 +175,7 @@ config CPU_IXP43X
config MACH_GTWX5715 config MACH_GTWX5715
bool "Gemtek WX5715 (Linksys WRV54G)" bool "Gemtek WX5715 (Linksys WRV54G)"
depends on ARCH_IXP4XX depends on ARCH_IXP4XX
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
This board is currently inside the Linksys WRV54G Gateways. This board is currently inside the Linksys WRV54G Gateways.
...@@ -196,7 +198,7 @@ config MACH_DEVIXP ...@@ -196,7 +198,7 @@ config MACH_DEVIXP
config MACH_MICCPT config MACH_MICCPT
bool "Omicron MICCPT" bool "Omicron MICCPT"
select FORCE_PCI depends on IXP4XX_PCI_LEGACY
help help
Say 'Y' here if you want your kernel to support the MICCPT Say 'Y' here if you want your kernel to support the MICCPT
board from OMICRON electronics GmbH. board from OMICRON electronics GmbH.
...@@ -209,9 +211,16 @@ config MACH_MIC256 ...@@ -209,9 +211,16 @@ config MACH_MIC256
comment "IXP4xx Options" comment "IXP4xx Options"
config IXP4XX_PCI_LEGACY
bool "IXP4xx legacy PCI driver support"
depends on PCI
help
Selects legacy PCI driver.
Not recommended for new development.
config IXP4XX_INDIRECT_PCI config IXP4XX_INDIRECT_PCI
bool "Use indirect PCI memory access" bool "Use indirect PCI memory access"
depends on PCI depends on IXP4XX_PCI_LEGACY
help help
IXP4xx provides two methods of accessing PCI memory space: IXP4xx provides two methods of accessing PCI memory space:
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
#include <linux/gpio/machine.h> #include <linux/gpio/machine.h>
#include <linux/platform_data/pata_ixp4xx_cf.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/memory.h> #include <asm/memory.h>
......
...@@ -27,12 +27,12 @@ ...@@ -27,12 +27,12 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/sched_clock.h> #include <linux/sched_clock.h>
#include <linux/soc/ixp4xx/cpu.h>
#include <linux/irqchip/irq-ixp4xx.h> #include <linux/irqchip/irq-ixp4xx.h>
#include <linux/platform_data/timer-ixp4xx.h> #include <linux/platform_data/timer-ixp4xx.h>
#include <linux/dma-map-ops.h> #include <linux/dma-map-ops.h>
#include <mach/udc.h> #include <mach/udc.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/io.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/exception.h> #include <asm/exception.h>
...@@ -44,6 +44,27 @@ ...@@ -44,6 +44,27 @@
#include "irqs.h" #include "irqs.h"
u32 ixp4xx_read_feature_bits(void)
{
u32 val = ~__raw_readl(IXP4XX_EXP_CFG2);
if (cpu_is_ixp42x_rev_a0())
return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
IXP4XX_FEATURE_AES);
if (cpu_is_ixp42x())
return val & IXP42X_FEATURE_MASK;
if (cpu_is_ixp43x())
return val & IXP43X_FEATURE_MASK;
return val & IXP46X_FEATURE_MASK;
}
EXPORT_SYMBOL(ixp4xx_read_feature_bits);
void ixp4xx_write_feature_bits(u32 value)
{
__raw_writel(~value, IXP4XX_EXP_CFG2);
}
EXPORT_SYMBOL(ixp4xx_write_feature_bits);
#define IXP4XX_TIMER_FREQ 66666000 #define IXP4XX_TIMER_FREQ 66666000
/************************************************************************* /*************************************************************************
...@@ -215,6 +236,27 @@ static struct resource ixp46x_i2c_resources[] = { ...@@ -215,6 +236,27 @@ static struct resource ixp46x_i2c_resources[] = {
} }
}; };
/* A single 32-bit register on IXP46x */
#define IXP4XX_HWRANDOM_BASE_PHYS 0x70002100
static struct resource ixp46x_hwrandom_resource[] = {
{
.start = IXP4XX_HWRANDOM_BASE_PHYS,
.end = IXP4XX_HWRANDOM_BASE_PHYS + 0x3,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device ixp46x_hwrandom_device = {
.name = "ixp4xx-hwrandom",
.id = -1,
.dev = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.resource = ixp46x_hwrandom_resource,
.num_resources = ARRAY_SIZE(ixp46x_hwrandom_resource),
};
/* /*
* I2C controller. The IXP46x uses the same block as the IOP3xx, so * I2C controller. The IXP46x uses the same block as the IOP3xx, so
* we just use the same device name. * we just use the same device name.
...@@ -227,7 +269,8 @@ static struct platform_device ixp46x_i2c_controller = { ...@@ -227,7 +269,8 @@ static struct platform_device ixp46x_i2c_controller = {
}; };
static struct platform_device *ixp46x_devices[] __initdata = { static struct platform_device *ixp46x_devices[] __initdata = {
&ixp46x_i2c_controller &ixp46x_hwrandom_device,
&ixp46x_i2c_controller,
}; };
unsigned long ixp4xx_exp_bus_size; unsigned long ixp4xx_exp_bus_size;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/flash.h> #include <asm/mach/flash.h>
#include <mach/hardware.h>
#include "irqs.h" #include "irqs.h"
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "ixp4xx-regs.h" #include "ixp4xx-regs.h"
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
#include <mach/cpu.h> #include <linux/soc/ixp4xx/cpu.h>
#endif #endif
/* Platform helper functions and definitions */ /* Platform helper functions and definitions */
......
...@@ -45,21 +45,21 @@ ...@@ -45,21 +45,21 @@
* it can be used with the low-level debug code. * it can be used with the low-level debug code.
*/ */
#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000 #define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000
#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000) #define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEC00000)
#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000 #define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000
/* /*
* PCI Config registers * PCI Config registers
*/ */
#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000 #define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000
#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000) #define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEC13000)
#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000 #define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000
/* /*
* Expansion BUS Configuration registers * Expansion BUS Configuration registers
*/ */
#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000 #define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000
#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000 #define IXP4XX_EXP_CFG_BASE_VIRT 0xFEC14000
#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000 #define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000
#define IXP4XX_EXP_CS0_OFFSET 0x00 #define IXP4XX_EXP_CS0_OFFSET 0x00
...@@ -120,6 +120,7 @@ ...@@ -120,6 +120,7 @@
#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000) #define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
/* The UART is explicitly put in the beginning of fixmap */
#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000) #define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000) #define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000) #define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
...@@ -299,58 +300,4 @@ ...@@ -299,58 +300,4 @@
#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */ #define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
/* "fuse" bits of IXP_EXP_CFG2 */
/* All IXP4xx CPUs */
#define IXP4XX_FEATURE_RCOMP (1 << 0)
#define IXP4XX_FEATURE_USB_DEVICE (1 << 1)
#define IXP4XX_FEATURE_HASH (1 << 2)
#define IXP4XX_FEATURE_AES (1 << 3)
#define IXP4XX_FEATURE_DES (1 << 4)
#define IXP4XX_FEATURE_HDLC (1 << 5)
#define IXP4XX_FEATURE_AAL (1 << 6)
#define IXP4XX_FEATURE_HSS (1 << 7)
#define IXP4XX_FEATURE_UTOPIA (1 << 8)
#define IXP4XX_FEATURE_NPEB_ETH0 (1 << 9)
#define IXP4XX_FEATURE_NPEC_ETH (1 << 10)
#define IXP4XX_FEATURE_RESET_NPEA (1 << 11)
#define IXP4XX_FEATURE_RESET_NPEB (1 << 12)
#define IXP4XX_FEATURE_RESET_NPEC (1 << 13)
#define IXP4XX_FEATURE_PCI (1 << 14)
#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
#define IXP4XX_FEATURE_XSCALE_MAX_FREQ (3 << 22)
#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP | \
IXP4XX_FEATURE_USB_DEVICE | \
IXP4XX_FEATURE_HASH | \
IXP4XX_FEATURE_AES | \
IXP4XX_FEATURE_DES | \
IXP4XX_FEATURE_HDLC | \
IXP4XX_FEATURE_AAL | \
IXP4XX_FEATURE_HSS | \
IXP4XX_FEATURE_UTOPIA | \
IXP4XX_FEATURE_NPEB_ETH0 | \
IXP4XX_FEATURE_NPEC_ETH | \
IXP4XX_FEATURE_RESET_NPEA | \
IXP4XX_FEATURE_RESET_NPEB | \
IXP4XX_FEATURE_RESET_NPEC | \
IXP4XX_FEATURE_PCI | \
IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
IXP4XX_FEATURE_XSCALE_MAX_FREQ)
/* IXP43x/46x CPUs */
#define IXP4XX_FEATURE_ECC_TIMESYNC (1 << 15)
#define IXP4XX_FEATURE_USB_HOST (1 << 18)
#define IXP4XX_FEATURE_NPEA_ETH (1 << 19)
#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK | \
IXP4XX_FEATURE_ECC_TIMESYNC | \
IXP4XX_FEATURE_USB_HOST | \
IXP4XX_FEATURE_NPEA_ETH)
/* IXP46x CPU (including IXP455) only */
#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3 (1 << 20)
#define IXP4XX_FEATURE_RSA (1 << 21)
#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK | \
IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \
IXP4XX_FEATURE_RSA)
#endif #endif
...@@ -79,20 +79,6 @@ extern unsigned long ixp4xx_exp_bus_size; ...@@ -79,20 +79,6 @@ extern unsigned long ixp4xx_exp_bus_size;
#define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66MHzi APB BUS */ #define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66MHzi APB BUS */
#define IXP4XX_UART_XTAL 14745600 #define IXP4XX_UART_XTAL 14745600
/*
* This structure provide a means for the board setup code
* to give information to th pata_ixp4xx driver. It is
* passed as platform_data.
*/
struct ixp4xx_pata_data {
volatile u32 *cs0_cfg;
volatile u32 *cs1_cfg;
unsigned long cs0_bits;
unsigned long cs1_bits;
void __iomem *cs0;
void __iomem *cs1;
};
/* /*
* Frequency of clock used for primary clocksource * Frequency of clock used for primary clocksource
*/ */
......
...@@ -9,8 +9,12 @@ ...@@ -9,8 +9,12 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <mach/hardware.h> /*
#include <mach/ixp4xx-regs.h> * These are the only fixed phys to virt mappings we ever need
* we put it right after the UART mapping at 0xffc80000-0xffc81fff
*/
#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000
#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEC14000
static struct map_desc ixp4xx_of_io_desc[] __initdata = { static struct map_desc ixp4xx_of_io_desc[] __initdata = {
/* /*
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/flash.h> #include <asm/mach/flash.h>
#include <mach/hardware.h>
#include "irqs.h" #include "irqs.h"
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/flash.h> #include <asm/mach/flash.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <mach/hardware.h>
#include "irqs.h" #include "irqs.h"
......
...@@ -65,14 +65,14 @@ config MACH_OMAP_INNOVATOR ...@@ -65,14 +65,14 @@ config MACH_OMAP_INNOVATOR
config MACH_OMAP_H2 config MACH_OMAP_H2
bool "TI H2 Support" bool "TI H2 Support"
depends on ARCH_OMAP16XX depends on ARCH_OMAP16XX
help help
TI OMAP 1610/1611B H2 board support. Say Y here if you have such TI OMAP 1610/1611B H2 board support. Say Y here if you have such
a board. a board.
config MACH_OMAP_H3 config MACH_OMAP_H3
bool "TI H3 Support" bool "TI H3 Support"
depends on ARCH_OMAP16XX depends on ARCH_OMAP16XX
help help
TI OMAP 1710 H3 board support. Say Y here if you have such TI OMAP 1710 H3 board support. Say Y here if you have such
a board. a board.
...@@ -85,14 +85,14 @@ config MACH_HERALD ...@@ -85,14 +85,14 @@ config MACH_HERALD
config MACH_OMAP_OSK config MACH_OMAP_OSK
bool "TI OSK Support" bool "TI OSK Support"
depends on ARCH_OMAP16XX depends on ARCH_OMAP16XX
help help
TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
if you have such a board. if you have such a board.
config OMAP_OSK_MISTRAL config OMAP_OSK_MISTRAL
bool "Mistral QVGA board Support" bool "Mistral QVGA board Support"
depends on MACH_OMAP_OSK depends on MACH_OMAP_OSK
help help
The OSK supports an optional add-on board with a Quarter-VGA The OSK supports an optional add-on board with a Quarter-VGA
touchscreen, PDA-ish buttons, a resume button, bicolor LED, touchscreen, PDA-ish buttons, a resume button, bicolor LED,
and camera connector. Say Y here if you have this board. and camera connector. Say Y here if you have this board.
...@@ -100,14 +100,14 @@ config OMAP_OSK_MISTRAL ...@@ -100,14 +100,14 @@ config OMAP_OSK_MISTRAL
config MACH_OMAP_PERSEUS2 config MACH_OMAP_PERSEUS2
bool "TI Perseus2" bool "TI Perseus2"
depends on ARCH_OMAP730 depends on ARCH_OMAP730
help help
Support for TI OMAP 730 Perseus2 board. Say Y here if you have such Support for TI OMAP 730 Perseus2 board. Say Y here if you have such
a board. a board.
config MACH_OMAP_FSAMPLE config MACH_OMAP_FSAMPLE
bool "TI F-Sample" bool "TI F-Sample"
depends on ARCH_OMAP730 depends on ARCH_OMAP730
help help
Support for TI OMAP 850 F-Sample board. Say Y here if you have such Support for TI OMAP 850 F-Sample board. Say Y here if you have such
a board. a board.
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
extern struct omap_domain_base cm_base; extern struct omap_domain_base cm_base;
extern struct omap_domain_base cm2_base; extern struct omap_domain_base cm2_base;
extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
# endif # endif
/* /*
......
...@@ -37,19 +37,6 @@ struct omap_domain_base cm2_base; ...@@ -37,19 +37,6 @@ struct omap_domain_base cm2_base;
#define CM_NO_CLOCKS 0x1 #define CM_NO_CLOCKS 0x1
#define CM_SINGLE_INSTANCE 0x2 #define CM_SINGLE_INSTANCE 0x2
/**
* omap2_set_globals_cm - set the CM/CM2 base addresses (for early use)
* @cm: CM base virtual address
* @cm2: CM2 base virtual address (if present on the booted SoC)
*
* XXX Will be replaced when the PRM/CM drivers are completed.
*/
void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2)
{
cm_base.va = cm;
cm2_base.va = cm2;
}
/** /**
* cm_split_idlest_reg - split CM_IDLEST reg addr into its components * cm_split_idlest_reg - split CM_IDLEST reg addr into its components
* @idlest_reg: CM_IDLEST* virtual address * @idlest_reg: CM_IDLEST* virtual address
......
...@@ -130,7 +130,6 @@ void am33xx_init_early(void); ...@@ -130,7 +130,6 @@ void am33xx_init_early(void);
void am35xx_init_early(void); void am35xx_init_early(void);
void ti814x_init_early(void); void ti814x_init_early(void);
void ti816x_init_early(void); void ti816x_init_early(void);
void am33xx_init_early(void);
void am43xx_init_early(void); void am43xx_init_early(void);
void am43xx_init_late(void); void am43xx_init_late(void);
void omap4430_init_early(void); void omap4430_init_early(void);
......
...@@ -136,11 +136,6 @@ struct omap3_control_regs { ...@@ -136,11 +136,6 @@ struct omap3_control_regs {
static struct omap3_control_regs control_context; static struct omap3_control_regs control_context;
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */ #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
void __init omap2_set_globals_control(void __iomem *ctrl)
{
omap2_ctrl_base = ctrl;
}
u8 omap_ctrl_readb(u16 offset) u8 omap_ctrl_readb(u16 offset)
{ {
u32 val; u32 val;
......
...@@ -528,7 +528,6 @@ extern int omap3_ctrl_save_padconf(void); ...@@ -528,7 +528,6 @@ extern int omap3_ctrl_save_padconf(void);
void omap3_ctrl_init(void); void omap3_ctrl_init(void);
int omap2_control_base_init(void); int omap2_control_base_init(void);
int omap_control_init(void); int omap_control_init(void);
void omap2_set_globals_control(void __iomem *ctrl);
void __init omap3_control_legacy_iomap_init(void); void __init omap3_control_legacy_iomap_init(void);
#else #else
#define omap_ctrl_readb(x) 0 #define omap_ctrl_readb(x) 0
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/cpuidle.h> #include <linux/cpuidle.h>
#include <linux/platform_data/pm33xx.h> #include <linux/platform_data/pm33xx.h>
#include <linux/suspend.h>
#include <asm/cpuidle.h> #include <asm/cpuidle.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/suspend.h> #include <asm/suspend.h>
...@@ -324,6 +325,44 @@ static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void) ...@@ -324,6 +325,44 @@ static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
return NULL; return NULL;
} }
#ifdef CONFIG_SUSPEND
/*
* Block system suspend initially. Later on pm33xx sets up it's own
* platform_suspend_ops after probe. That depends also on loaded
* wkup_m3_ipc and booted am335x-pm-firmware.elf.
*/
static int amx3_suspend_block(suspend_state_t state)
{
pr_warn("PM not initialized for pm33xx, wkup_m3_ipc, or am335x-pm-firmware.elf\n");
return -EINVAL;
}
static int amx3_pm_valid(suspend_state_t state)
{
switch (state) {
case PM_SUSPEND_STANDBY:
return 1;
default:
return 0;
}
}
static const struct platform_suspend_ops amx3_blocked_pm_ops = {
.begin = amx3_suspend_block,
.valid = amx3_pm_valid,
};
static void __init amx3_block_suspend(void)
{
suspend_set_ops(&amx3_blocked_pm_ops);
}
#else
static inline void amx3_block_suspend(void)
{
}
#endif /* CONFIG_SUSPEND */
int __init amx3_common_pm_init(void) int __init amx3_common_pm_init(void)
{ {
struct am33xx_pm_platform_data *pdata; struct am33xx_pm_platform_data *pdata;
...@@ -337,6 +376,7 @@ int __init amx3_common_pm_init(void) ...@@ -337,6 +376,7 @@ int __init amx3_common_pm_init(void)
devinfo.size_data = sizeof(*pdata); devinfo.size_data = sizeof(*pdata);
devinfo.id = -1; devinfo.id = -1;
platform_device_register_full(&devinfo); platform_device_register_full(&devinfo);
amx3_block_suspend();
return 0; return 0;
} }
......
...@@ -271,7 +271,6 @@ static int rx1950_led_blink_set(struct gpio_desc *desc, int state, ...@@ -271,7 +271,6 @@ static int rx1950_led_blink_set(struct gpio_desc *desc, int state,
break; break;
default: default:
return -EINVAL; return -EINVAL;
break;
} }
if (delay_on && delay_off && !*delay_on && !*delay_off) if (delay_on && delay_off && !*delay_on && !*delay_off)
......
...@@ -16,6 +16,7 @@ config ARCH_SUNXI ...@@ -16,6 +16,7 @@ config ARCH_SUNXI
select IRQ_FASTEOI_HIERARCHY_HANDLERS select IRQ_FASTEOI_HIERARCHY_HANDLERS
select PINCTRL select PINCTRL
select RESET_CONTROLLER select RESET_CONTROLLER
select SUN4I_TIMER
help help
This enables support for Allwinner sunxi based SoCs like the A64. This enables support for Allwinner sunxi based SoCs like the A64.
......
...@@ -79,7 +79,7 @@ &ehci1 { ...@@ -79,7 +79,7 @@ &ehci1 {
&emac { &emac {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>; pinctrl-0 = <&rgmii_pins>;
phy-mode = "rgmii-id"; phy-mode = "rgmii-txid";
phy-handle = <&ext_rgmii_phy>; phy-handle = <&ext_rgmii_phy>;
phy-supply = <&reg_dc1sw>; phy-supply = <&reg_dc1sw>;
status = "okay"; status = "okay";
......
...@@ -227,7 +227,7 @@ pcie0: pcie@f8000000 { ...@@ -227,7 +227,7 @@ pcie0: pcie@f8000000 {
<&pcie_phy 2>, <&pcie_phy 3>; <&pcie_phy 2>, <&pcie_phy 3>;
phy-names = "pcie-phy-0", "pcie-phy-1", phy-names = "pcie-phy-0", "pcie-phy-1",
"pcie-phy-2", "pcie-phy-3"; "pcie-phy-2", "pcie-phy-3";
ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x1e00000>, ranges = <0x82000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x1e00000>,
<0x81000000 0x0 0xfbe00000 0x0 0xfbe00000 0x0 0x100000>; <0x81000000 0x0 0xfbe00000 0x0 0xfbe00000 0x0 0x100000>;
resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>,
<&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>, <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>,
......
...@@ -1058,7 +1058,7 @@ config PATA_ISAPNP ...@@ -1058,7 +1058,7 @@ config PATA_ISAPNP
config PATA_IXP4XX_CF config PATA_IXP4XX_CF
tristate "IXP4XX Compact Flash support" tristate "IXP4XX Compact Flash support"
depends on ARCH_IXP4XX depends on ARCH_IXP4XX || COMPILE_TEST
help help
This option enables support for a Compact Flash connected on This option enables support for a Compact Flash connected on
the ixp4xx expansion bus. This driver had been written for the ixp4xx expansion bus. This driver had been written for
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/pata_ixp4xx_cf.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#define DRV_NAME "pata_ixp4xx_cf" #define DRV_NAME "pata_ixp4xx_cf"
......
...@@ -152,7 +152,7 @@ config HW_RANDOM_VIA ...@@ -152,7 +152,7 @@ config HW_RANDOM_VIA
config HW_RANDOM_IXP4XX config HW_RANDOM_IXP4XX
tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support" tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support"
depends on ARCH_IXP4XX depends on ARCH_IXP4XX || COMPILE_TEST
default HW_RANDOM default HW_RANDOM
help help
This driver provides kernel-side support for the Pseudo-Random This driver provides kernel-side support for the Pseudo-Random
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* drivers/char/hw_random/ixp4xx-rng.c * drivers/char/hw_random/ixp4xx-rng.c
* *
...@@ -8,23 +9,20 @@ ...@@ -8,23 +9,20 @@
* Copyright 2005 (c) MontaVista Software, Inc. * Copyright 2005 (c) MontaVista Software, Inc.
* *
* Fixes by Michael Buesch * Fixes by Michael Buesch
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/hw_random.h> #include <linux/hw_random.h>
#include <linux/of.h>
#include <linux/soc/ixp4xx/cpu.h>
#include <asm/io.h> #include <asm/io.h>
#include <mach/hardware.h>
static int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer) static int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer)
{ {
...@@ -40,35 +38,40 @@ static struct hwrng ixp4xx_rng_ops = { ...@@ -40,35 +38,40 @@ static struct hwrng ixp4xx_rng_ops = {
.data_read = ixp4xx_rng_data_read, .data_read = ixp4xx_rng_data_read,
}; };
static int __init ixp4xx_rng_init(void) static int ixp4xx_rng_probe(struct platform_device *pdev)
{ {
void __iomem * rng_base; void __iomem * rng_base;
int err; struct device *dev = &pdev->dev;
struct resource *res;
if (!cpu_is_ixp46x()) /* includes IXP455 */ if (!cpu_is_ixp46x()) /* includes IXP455 */
return -ENOSYS; return -ENOSYS;
rng_base = ioremap(0x70002100, 4); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!rng_base) rng_base = devm_ioremap_resource(dev, res);
return -ENOMEM; if (IS_ERR(rng_base))
ixp4xx_rng_ops.priv = (unsigned long)rng_base; return PTR_ERR(rng_base);
err = hwrng_register(&ixp4xx_rng_ops);
if (err)
iounmap(rng_base);
return err; ixp4xx_rng_ops.priv = (unsigned long)rng_base;
return devm_hwrng_register(dev, &ixp4xx_rng_ops);
} }
static void __exit ixp4xx_rng_exit(void) static const struct of_device_id ixp4xx_rng_of_match[] = {
{ {
void __iomem * rng_base = (void __iomem *)ixp4xx_rng_ops.priv; .compatible = "intel,ixp46x-rng",
},
hwrng_unregister(&ixp4xx_rng_ops); {},
iounmap(rng_base); };
} MODULE_DEVICE_TABLE(of, ixp4xx_rng_of_match);
module_init(ixp4xx_rng_init); static struct platform_driver ixp4xx_rng_driver = {
module_exit(ixp4xx_rng_exit); .driver = {
.name = "ixp4xx-hwrandom",
.of_match_table = ixp4xx_rng_of_match,
},
.probe = ixp4xx_rng_probe,
};
module_platform_driver(ixp4xx_rng_driver);
MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x"); MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x");
......
...@@ -31,6 +31,10 @@ ...@@ -31,6 +31,10 @@
#include <linux/soc/ixp4xx/npe.h> #include <linux/soc/ixp4xx/npe.h>
#include <linux/soc/ixp4xx/qmgr.h> #include <linux/soc/ixp4xx/qmgr.h>
/* Intermittent includes, delete this after v5.14-rc1 */
#include <linux/soc/ixp4xx/cpu.h>
#include <mach/ixp4xx-regs.h>
#define MAX_KEYLEN 32 #define MAX_KEYLEN 32
/* hash: cfgword + 2 * digestlen; crypt: keylen + cfgword */ /* hash: cfgword + 2 * digestlen; crypt: keylen + cfgword */
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/soc/ixp4xx/npe.h> #include <linux/soc/ixp4xx/npe.h>
#include <linux/soc/ixp4xx/qmgr.h> #include <linux/soc/ixp4xx/qmgr.h>
#include <mach/hardware.h>
#include <linux/soc/ixp4xx/cpu.h>
#include "ixp46x_ts.h" #include "ixp46x_ts.h"
......
...@@ -12,9 +12,8 @@ ...@@ -12,9 +12,8 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ptp_clock_kernel.h> #include <linux/ptp_clock_kernel.h>
#include <linux/soc/ixp4xx/cpu.h>
#include "ixp46x_ts.h" #include "ixp46x_ts.h"
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/soc/ixp4xx/npe.h> #include <linux/soc/ixp4xx/npe.h>
#include <linux/soc/ixp4xx/qmgr.h> #include <linux/soc/ixp4xx/qmgr.h>
#include <linux/soc/ixp4xx/cpu.h>
#define DEBUG_DESC 0 #define DEBUG_DESC 0
#define DEBUG_RX 0 #define DEBUG_RX 0
......
...@@ -37,6 +37,14 @@ config PCI_FTPCI100 ...@@ -37,6 +37,14 @@ config PCI_FTPCI100
depends on OF depends on OF
default ARCH_GEMINI default ARCH_GEMINI
config PCI_IXP4XX
bool "Intel IXP4xx PCI controller"
depends on ARM && OF
default ARCH_IXP4XX
help
Say Y here if you want support for the PCI host controller found
in the Intel IXP4xx XScale-based network processor SoC.
config PCI_TEGRA config PCI_TEGRA
bool "NVIDIA Tegra PCIe controller" bool "NVIDIA Tegra PCIe controller"
depends on ARCH_TEGRA || COMPILE_TEST depends on ARCH_TEGRA || COMPILE_TEST
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PCIE_CADENCE) += cadence/ obj-$(CONFIG_PCIE_CADENCE) += cadence/
obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o
obj-$(CONFIG_PCI_IXP4XX) += pci-ixp4xx.o
obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
obj-$(CONFIG_PCI_HYPERV_INTERFACE) += pci-hyperv-intf.o obj-$(CONFIG_PCI_HYPERV_INTERFACE) += pci-hyperv-intf.o
obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
......
This diff is collapsed.
...@@ -70,6 +70,9 @@ static int __init imx_soc_device_init(void) ...@@ -70,6 +70,9 @@ static int __init imx_soc_device_init(void)
case MXC_CPU_MX35: case MXC_CPU_MX35:
soc_id = "i.MX35"; soc_id = "i.MX35";
break; break;
case MXC_CPU_MX50:
soc_id = "i.MX50";
break;
case MXC_CPU_MX51: case MXC_CPU_MX51:
ocotp_compat = "fsl,imx51-iim"; ocotp_compat = "fsl,imx51-iim";
soc_id = "i.MX51"; soc_id = "i.MX51";
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/soc/ixp4xx/npe.h> #include <linux/soc/ixp4xx/npe.h>
#include <mach/hardware.h>
#include <linux/soc/ixp4xx/cpu.h>
#define DEBUG_MSG 0 #define DEBUG_MSG 0
#define DEBUG_FW 0 #define DEBUG_FW 0
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/soc/ixp4xx/qmgr.h> #include <linux/soc/ixp4xx/qmgr.h>
#include <mach/hardware.h>
#include <linux/soc/ixp4xx/cpu.h>
static struct qmgr_regs __iomem *qmgr_regs; static struct qmgr_regs __iomem *qmgr_regs;
static int qmgr_irq_1; static int qmgr_irq_1;
......
...@@ -144,6 +144,8 @@ config SOC_TEGRA_FLOWCTRL ...@@ -144,6 +144,8 @@ config SOC_TEGRA_FLOWCTRL
config SOC_TEGRA_PMC config SOC_TEGRA_PMC
bool bool
select GENERIC_PINCONF select GENERIC_PINCONF
select PM_OPP
select PM_GENERIC_DOMAINS
config SOC_TEGRA_POWERGATE_BPMP config SOC_TEGRA_POWERGATE_BPMP
def_bool y def_bool y
......
...@@ -3,9 +3,16 @@ ...@@ -3,9 +3,16 @@
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved. * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
*/ */
#define dev_fmt(fmt) "tegra-soc: " fmt
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/pm_opp.h>
#include <soc/tegra/common.h> #include <soc/tegra/common.h>
#include <soc/tegra/fuse.h>
static const struct of_device_id tegra_machine_match[] = { static const struct of_device_id tegra_machine_match[] = {
{ .compatible = "nvidia,tegra20", }, { .compatible = "nvidia,tegra20", },
...@@ -31,3 +38,93 @@ bool soc_is_tegra(void) ...@@ -31,3 +38,93 @@ bool soc_is_tegra(void)
return match != NULL; return match != NULL;
} }
static int tegra_core_dev_init_opp_state(struct device *dev)
{
unsigned long rate;
struct clk *clk;
int err;
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
dev_err(dev, "failed to get clk: %pe\n", clk);
return PTR_ERR(clk);
}
rate = clk_get_rate(clk);
if (!rate) {
dev_err(dev, "failed to get clk rate\n");
return -EINVAL;
}
/* first dummy rate-setting initializes voltage vote */
err = dev_pm_opp_set_rate(dev, rate);
if (err) {
dev_err(dev, "failed to initialize OPP clock: %d\n", err);
return err;
}
return 0;
}
/**
* devm_tegra_core_dev_init_opp_table() - initialize OPP table
* @dev: device for which OPP table is initialized
* @params: pointer to the OPP table configuration
*
* This function will initialize OPP table and sync OPP state of a Tegra SoC
* core device.
*
* Return: 0 on success or errorno.
*/
int devm_tegra_core_dev_init_opp_table(struct device *dev,
struct tegra_core_opp_params *params)
{
u32 hw_version;
int err;
err = devm_pm_opp_set_clkname(dev, NULL);
if (err) {
dev_err(dev, "failed to set OPP clk: %d\n", err);
return err;
}
/* Tegra114+ doesn't support OPP yet */
if (!of_machine_is_compatible("nvidia,tegra20") &&
!of_machine_is_compatible("nvidia,tegra30"))
return -ENODEV;
if (of_machine_is_compatible("nvidia,tegra20"))
hw_version = BIT(tegra_sku_info.soc_process_id);
else
hw_version = BIT(tegra_sku_info.soc_speedo_id);
err = devm_pm_opp_set_supported_hw(dev, &hw_version, 1);
if (err) {
dev_err(dev, "failed to set OPP supported HW: %d\n", err);
return err;
}
/*
* Older device-trees have an empty OPP table, we will get
* -ENODEV from devm_pm_opp_of_add_table() in this case.
*/
err = devm_pm_opp_of_add_table(dev);
if (err) {
if (err == -ENODEV)
dev_err_once(dev, "OPP table not found, please update device-tree\n");
else
dev_err(dev, "failed to add OPP table: %d\n", err);
return err;
}
if (params->init_state) {
err = tegra_core_dev_init_opp_state(dev);
if (err)
return err;
}
return 0;
}
EXPORT_SYMBOL_GPL(devm_tegra_core_dev_init_opp_table);
...@@ -489,10 +489,8 @@ static int __init tegra_init_fuse(void) ...@@ -489,10 +489,8 @@ static int __init tegra_init_fuse(void)
size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups; size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups;
fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL); fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL);
if (!fuse->lookups) if (fuse->lookups)
return -ENOMEM; nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups);
nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups);
} }
return 0; return 0;
......
...@@ -37,7 +37,8 @@ ...@@ -37,7 +37,8 @@
defined(CONFIG_ARCH_TEGRA_132_SOC) || \ defined(CONFIG_ARCH_TEGRA_132_SOC) || \
defined(CONFIG_ARCH_TEGRA_210_SOC) || \ defined(CONFIG_ARCH_TEGRA_210_SOC) || \
defined(CONFIG_ARCH_TEGRA_186_SOC) || \ defined(CONFIG_ARCH_TEGRA_186_SOC) || \
defined(CONFIG_ARCH_TEGRA_194_SOC) defined(CONFIG_ARCH_TEGRA_194_SOC) || \
defined(CONFIG_ARCH_TEGRA_234_SOC)
static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset) static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset)
{ {
if (WARN_ON(!fuse->base)) if (WARN_ON(!fuse->base))
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_domain.h> #include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/reset.h> #include <linux/reset.h>
...@@ -428,6 +429,9 @@ struct tegra_pmc { ...@@ -428,6 +429,9 @@ struct tegra_pmc {
struct irq_chip irq; struct irq_chip irq;
struct notifier_block clk_nb; struct notifier_block clk_nb;
bool core_domain_state_synced;
bool core_domain_registered;
}; };
static struct tegra_pmc *pmc = &(struct tegra_pmc) { static struct tegra_pmc *pmc = &(struct tegra_pmc) {
...@@ -1297,12 +1301,107 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) ...@@ -1297,12 +1301,107 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
return err; return err;
} }
bool tegra_pmc_core_domain_state_synced(void)
{
return pmc->core_domain_state_synced;
}
static int
tegra_pmc_core_pd_set_performance_state(struct generic_pm_domain *genpd,
unsigned int level)
{
struct dev_pm_opp *opp;
int err;
opp = dev_pm_opp_find_level_ceil(&genpd->dev, &level);
if (IS_ERR(opp)) {
dev_err(&genpd->dev, "failed to find OPP for level %u: %pe\n",
level, opp);
return PTR_ERR(opp);
}
mutex_lock(&pmc->powergates_lock);
err = dev_pm_opp_set_opp(pmc->dev, opp);
mutex_unlock(&pmc->powergates_lock);
dev_pm_opp_put(opp);
if (err) {
dev_err(&genpd->dev, "failed to set voltage to %duV: %d\n",
level, err);
return err;
}
return 0;
}
static unsigned int
tegra_pmc_core_pd_opp_to_performance_state(struct generic_pm_domain *genpd,
struct dev_pm_opp *opp)
{
return dev_pm_opp_get_level(opp);
}
static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
{
struct generic_pm_domain *genpd;
const char *rname = "core";
int err;
genpd = devm_kzalloc(pmc->dev, sizeof(*genpd), GFP_KERNEL);
if (!genpd)
return -ENOMEM;
genpd->name = np->name;
genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state;
genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state;
err = devm_pm_opp_set_regulators(pmc->dev, &rname, 1);
if (err)
return dev_err_probe(pmc->dev, err,
"failed to set core OPP regulator\n");
err = pm_genpd_init(genpd, NULL, false);
if (err) {
dev_err(pmc->dev, "failed to init core genpd: %d\n", err);
return err;
}
err = of_genpd_add_provider_simple(np, genpd);
if (err) {
dev_err(pmc->dev, "failed to add core genpd: %d\n", err);
goto remove_genpd;
}
pmc->core_domain_registered = true;
return 0;
remove_genpd:
pm_genpd_remove(genpd);
return err;
}
static int tegra_powergate_init(struct tegra_pmc *pmc, static int tegra_powergate_init(struct tegra_pmc *pmc,
struct device_node *parent) struct device_node *parent)
{ {
struct of_phandle_args child_args, parent_args;
struct device_node *np, *child; struct device_node *np, *child;
int err = 0; int err = 0;
/*
* Core power domain is the parent of powergate domains, hence it
* should be registered first.
*/
np = of_get_child_by_name(parent, "core-domain");
if (np) {
err = tegra_pmc_core_pd_add(pmc, np);
of_node_put(np);
if (err)
return err;
}
np = of_get_child_by_name(parent, "powergates"); np = of_get_child_by_name(parent, "powergates");
if (!np) if (!np)
return 0; return 0;
...@@ -1313,6 +1412,21 @@ static int tegra_powergate_init(struct tegra_pmc *pmc, ...@@ -1313,6 +1412,21 @@ static int tegra_powergate_init(struct tegra_pmc *pmc,
of_node_put(child); of_node_put(child);
break; break;
} }
if (of_parse_phandle_with_args(child, "power-domains",
"#power-domain-cells",
0, &parent_args))
continue;
child_args.np = child;
child_args.args_count = 0;
err = of_genpd_add_subdomain(&parent_args, &child_args);
of_node_put(parent_args.np);
if (err) {
of_node_put(child);
break;
}
} }
of_node_put(np); of_node_put(np);
...@@ -1356,6 +1470,12 @@ static void tegra_powergate_remove_all(struct device_node *parent) ...@@ -1356,6 +1470,12 @@ static void tegra_powergate_remove_all(struct device_node *parent)
} }
of_node_put(np); of_node_put(np);
np = of_get_child_by_name(parent, "core-domain");
if (np) {
of_genpd_del_provider(np);
of_genpd_remove_last(np);
}
} }
static const struct tegra_io_pad_soc * static const struct tegra_io_pad_soc *
...@@ -3667,6 +3787,29 @@ static const struct of_device_id tegra_pmc_match[] = { ...@@ -3667,6 +3787,29 @@ static const struct of_device_id tegra_pmc_match[] = {
{ } { }
}; };
static void tegra_pmc_sync_state(struct device *dev)
{
int err;
/*
* Older device-trees don't have core PD, and thus, there are
* no dependencies that will block the state syncing. We shouldn't
* mark the domain as synced in this case.
*/
if (!pmc->core_domain_registered)
return;
pmc->core_domain_state_synced = true;
/* this is a no-op if core regulator isn't used */
mutex_lock(&pmc->powergates_lock);
err = dev_pm_opp_sync_regulators(dev);
mutex_unlock(&pmc->powergates_lock);
if (err)
dev_err(dev, "failed to sync regulators: %d\n", err);
}
static struct platform_driver tegra_pmc_driver = { static struct platform_driver tegra_pmc_driver = {
.driver = { .driver = {
.name = "tegra-pmc", .name = "tegra-pmc",
...@@ -3675,6 +3818,7 @@ static struct platform_driver tegra_pmc_driver = { ...@@ -3675,6 +3818,7 @@ static struct platform_driver tegra_pmc_driver = {
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
.pm = &tegra_pmc_pm_ops, .pm = &tegra_pmc_pm_ops,
#endif #endif
.sync_state = tegra_pmc_sync_state,
}, },
.probe = tegra_pmc_probe, .probe = tegra_pmc_probe,
}; };
......
...@@ -12,16 +12,22 @@ ...@@ -12,16 +12,22 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/reboot.h>
#include <linux/regulator/coupler.h> #include <linux/regulator/coupler.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <soc/tegra/pmc.h>
struct tegra_regulator_coupler { struct tegra_regulator_coupler {
struct regulator_coupler coupler; struct regulator_coupler coupler;
struct regulator_dev *core_rdev; struct regulator_dev *core_rdev;
struct regulator_dev *cpu_rdev; struct regulator_dev *cpu_rdev;
struct regulator_dev *rtc_rdev; struct regulator_dev *rtc_rdev;
int core_min_uV; struct notifier_block reboot_notifier;
int core_min_uV, cpu_min_uV;
bool sys_reboot_mode_req;
bool sys_reboot_mode;
}; };
static inline struct tegra_regulator_coupler * static inline struct tegra_regulator_coupler *
...@@ -38,6 +44,21 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra, ...@@ -38,6 +44,21 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
int core_cur_uV; int core_cur_uV;
int err; int err;
/*
* Tegra20 SoC has critical DVFS-capable devices that are
* permanently-active or active at a boot time, like EMC
* (DRAM controller) or Display controller for example.
*
* The voltage of a CORE SoC power domain shall not be dropped below
* a minimum level, which is determined by device's clock rate.
* This means that we can't fully allow CORE voltage scaling until
* the state of all DVFS-critical CORE devices is synced.
*/
if (tegra_pmc_core_domain_state_synced() && !tegra->sys_reboot_mode) {
pr_info_once("voltage state synced\n");
return 0;
}
if (tegra->core_min_uV > 0) if (tegra->core_min_uV > 0)
return tegra->core_min_uV; return tegra->core_min_uV;
...@@ -58,7 +79,7 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra, ...@@ -58,7 +79,7 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
*/ */
tegra->core_min_uV = core_max_uV; tegra->core_min_uV = core_max_uV;
pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV); pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
return tegra->core_min_uV; return tegra->core_min_uV;
} }
...@@ -242,6 +263,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra, ...@@ -242,6 +263,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
if (cpu_uV < 0) if (cpu_uV < 0)
return cpu_uV; return cpu_uV;
/* store boot voltage level */
if (!tegra->cpu_min_uV)
tegra->cpu_min_uV = cpu_uV;
/* /*
* CPU's regulator may not have any consumers, hence the voltage * CPU's regulator may not have any consumers, hence the voltage
* must not be changed in that case because CPU simply won't * must not be changed in that case because CPU simply won't
...@@ -250,6 +275,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra, ...@@ -250,6 +275,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
if (!cpu_min_uV_consumers) if (!cpu_min_uV_consumers)
cpu_min_uV = cpu_uV; cpu_min_uV = cpu_uV;
/* restore boot voltage level */
if (tegra->sys_reboot_mode)
cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV);
if (cpu_min_uV > cpu_uV) { if (cpu_min_uV > cpu_uV) {
err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev, err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
cpu_uV, cpu_min_uV); cpu_uV, cpu_min_uV);
...@@ -290,6 +319,8 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler, ...@@ -290,6 +319,8 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
return -EINVAL; return -EINVAL;
} }
tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req);
if (rdev == cpu_rdev) if (rdev == cpu_rdev)
return tegra20_cpu_voltage_update(tegra, cpu_rdev, return tegra20_cpu_voltage_update(tegra, cpu_rdev,
core_rdev, rtc_rdev); core_rdev, rtc_rdev);
...@@ -303,6 +334,51 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler, ...@@ -303,6 +334,51 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
return -EPERM; return -EPERM;
} }
static int tegra20_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra,
bool sys_reboot_mode)
{
int err;
if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev)
return 0;
WRITE_ONCE(tegra->sys_reboot_mode_req, true);
/*
* Some devices use CPU soft-reboot method and in this case we
* should ensure that voltages are sane for the reboot by restoring
* the minimum boot levels.
*/
err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
if (err)
return err;
err = regulator_sync_voltage_rdev(tegra->core_rdev);
if (err)
return err;
WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode);
return 0;
}
static int tegra20_regulator_reboot(struct notifier_block *notifier,
unsigned long event, void *cmd)
{
struct tegra_regulator_coupler *tegra;
int ret;
if (event != SYS_RESTART)
return NOTIFY_DONE;
tegra = container_of(notifier, struct tegra_regulator_coupler,
reboot_notifier);
ret = tegra20_regulator_prepare_reboot(tegra, true);
return notifier_from_errno(ret);
}
static int tegra20_regulator_attach(struct regulator_coupler *coupler, static int tegra20_regulator_attach(struct regulator_coupler *coupler,
struct regulator_dev *rdev) struct regulator_dev *rdev)
{ {
...@@ -335,6 +411,14 @@ static int tegra20_regulator_detach(struct regulator_coupler *coupler, ...@@ -335,6 +411,14 @@ static int tegra20_regulator_detach(struct regulator_coupler *coupler,
{ {
struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
/*
* We don't expect regulators to be decoupled during reboot,
* this may race with the reboot handler and shouldn't ever
* happen in practice.
*/
if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING))
return -EPERM;
if (tegra->core_rdev == rdev) { if (tegra->core_rdev == rdev) {
tegra->core_rdev = NULL; tegra->core_rdev = NULL;
return 0; return 0;
...@@ -359,13 +443,19 @@ static struct tegra_regulator_coupler tegra20_coupler = { ...@@ -359,13 +443,19 @@ static struct tegra_regulator_coupler tegra20_coupler = {
.detach_regulator = tegra20_regulator_detach, .detach_regulator = tegra20_regulator_detach,
.balance_voltage = tegra20_regulator_balance_voltage, .balance_voltage = tegra20_regulator_balance_voltage,
}, },
.reboot_notifier.notifier_call = tegra20_regulator_reboot,
}; };
static int __init tegra_regulator_coupler_init(void) static int __init tegra_regulator_coupler_init(void)
{ {
int err;
if (!of_machine_is_compatible("nvidia,tegra20")) if (!of_machine_is_compatible("nvidia,tegra20"))
return 0; return 0;
err = register_reboot_notifier(&tegra20_coupler.reboot_notifier);
WARN_ON(err);
return regulator_coupler_register(&tegra20_coupler.coupler); return regulator_coupler_register(&tegra20_coupler.coupler);
} }
arch_initcall(tegra_regulator_coupler_init); arch_initcall(tegra_regulator_coupler_init);
...@@ -12,17 +12,22 @@ ...@@ -12,17 +12,22 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/reboot.h>
#include <linux/regulator/coupler.h> #include <linux/regulator/coupler.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <soc/tegra/fuse.h> #include <soc/tegra/fuse.h>
#include <soc/tegra/pmc.h>
struct tegra_regulator_coupler { struct tegra_regulator_coupler {
struct regulator_coupler coupler; struct regulator_coupler coupler;
struct regulator_dev *core_rdev; struct regulator_dev *core_rdev;
struct regulator_dev *cpu_rdev; struct regulator_dev *cpu_rdev;
int core_min_uV; struct notifier_block reboot_notifier;
int core_min_uV, cpu_min_uV;
bool sys_reboot_mode_req;
bool sys_reboot_mode;
}; };
static inline struct tegra_regulator_coupler * static inline struct tegra_regulator_coupler *
...@@ -39,6 +44,21 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra, ...@@ -39,6 +44,21 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
int core_cur_uV; int core_cur_uV;
int err; int err;
/*
* Tegra30 SoC has critical DVFS-capable devices that are
* permanently-active or active at a boot time, like EMC
* (DRAM controller) or Display controller for example.
*
* The voltage of a CORE SoC power domain shall not be dropped below
* a minimum level, which is determined by device's clock rate.
* This means that we can't fully allow CORE voltage scaling until
* the state of all DVFS-critical CORE devices is synced.
*/
if (tegra_pmc_core_domain_state_synced() && !tegra->sys_reboot_mode) {
pr_info_once("voltage state synced\n");
return 0;
}
if (tegra->core_min_uV > 0) if (tegra->core_min_uV > 0)
return tegra->core_min_uV; return tegra->core_min_uV;
...@@ -59,7 +79,7 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra, ...@@ -59,7 +79,7 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
*/ */
tegra->core_min_uV = core_max_uV; tegra->core_min_uV = core_max_uV;
pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV); pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
return tegra->core_min_uV; return tegra->core_min_uV;
} }
...@@ -172,6 +192,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra, ...@@ -172,6 +192,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
if (cpu_uV < 0) if (cpu_uV < 0)
return cpu_uV; return cpu_uV;
/* store boot voltage level */
if (!tegra->cpu_min_uV)
tegra->cpu_min_uV = cpu_uV;
/* /*
* CPU's regulator may not have any consumers, hence the voltage * CPU's regulator may not have any consumers, hence the voltage
* must not be changed in that case because CPU simply won't * must not be changed in that case because CPU simply won't
...@@ -195,6 +219,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra, ...@@ -195,6 +219,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
if (err) if (err)
return err; return err;
/* restore boot voltage level */
if (tegra->sys_reboot_mode)
cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV);
if (core_min_limited_uV > core_uV) { if (core_min_limited_uV > core_uV) {
pr_err("core voltage constraint violated: %d %d %d\n", pr_err("core voltage constraint violated: %d %d %d\n",
core_uV, core_min_limited_uV, cpu_uV); core_uV, core_min_limited_uV, cpu_uV);
...@@ -263,9 +291,56 @@ static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler, ...@@ -263,9 +291,56 @@ static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler,
return -EINVAL; return -EINVAL;
} }
tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req);
return tegra30_voltage_update(tegra, cpu_rdev, core_rdev); return tegra30_voltage_update(tegra, cpu_rdev, core_rdev);
} }
static int tegra30_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra,
bool sys_reboot_mode)
{
int err;
if (!tegra->core_rdev || !tegra->cpu_rdev)
return 0;
WRITE_ONCE(tegra->sys_reboot_mode_req, true);
/*
* Some devices use CPU soft-reboot method and in this case we
* should ensure that voltages are sane for the reboot by restoring
* the minimum boot levels.
*/
err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
if (err)
return err;
err = regulator_sync_voltage_rdev(tegra->core_rdev);
if (err)
return err;
WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode);
return 0;
}
static int tegra30_regulator_reboot(struct notifier_block *notifier,
unsigned long event, void *cmd)
{
struct tegra_regulator_coupler *tegra;
int ret;
if (event != SYS_RESTART)
return NOTIFY_DONE;
tegra = container_of(notifier, struct tegra_regulator_coupler,
reboot_notifier);
ret = tegra30_regulator_prepare_reboot(tegra, true);
return notifier_from_errno(ret);
}
static int tegra30_regulator_attach(struct regulator_coupler *coupler, static int tegra30_regulator_attach(struct regulator_coupler *coupler,
struct regulator_dev *rdev) struct regulator_dev *rdev)
{ {
...@@ -292,6 +367,14 @@ static int tegra30_regulator_detach(struct regulator_coupler *coupler, ...@@ -292,6 +367,14 @@ static int tegra30_regulator_detach(struct regulator_coupler *coupler,
{ {
struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
/*
* We don't expect regulators to be decoupled during reboot,
* this may race with the reboot handler and shouldn't ever
* happen in practice.
*/
if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING))
return -EPERM;
if (tegra->core_rdev == rdev) { if (tegra->core_rdev == rdev) {
tegra->core_rdev = NULL; tegra->core_rdev = NULL;
return 0; return 0;
...@@ -311,13 +394,19 @@ static struct tegra_regulator_coupler tegra30_coupler = { ...@@ -311,13 +394,19 @@ static struct tegra_regulator_coupler tegra30_coupler = {
.detach_regulator = tegra30_regulator_detach, .detach_regulator = tegra30_regulator_detach,
.balance_voltage = tegra30_regulator_balance_voltage, .balance_voltage = tegra30_regulator_balance_voltage,
}, },
.reboot_notifier.notifier_call = tegra30_regulator_reboot,
}; };
static int __init tegra_regulator_coupler_init(void) static int __init tegra_regulator_coupler_init(void)
{ {
int err;
if (!of_machine_is_compatible("nvidia,tegra30")) if (!of_machine_is_compatible("nvidia,tegra30"))
return 0; return 0;
err = register_reboot_notifier(&tegra30_coupler.reboot_notifier);
WARN_ON(err);
return regulator_coupler_register(&tegra30_coupler.coupler); return regulator_coupler_register(&tegra30_coupler.coupler);
} }
arch_initcall(tegra_regulator_coupler_init); arch_initcall(tegra_regulator_coupler_init);
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PLATFORM_DATA_PATA_IXP4XX_H
#define __PLATFORM_DATA_PATA_IXP4XX_H
#include <linux/types.h>
/*
* This structure provide a means for the board setup code
* to give information to th pata_ixp4xx driver. It is
* passed as platform_data.
*/
struct ixp4xx_pata_data {
volatile u32 *cs0_cfg;
volatile u32 *cs1_cfg;
unsigned long cs0_bits;
unsigned long cs1_bits;
void __iomem *cs0;
void __iomem *cs1;
};
#endif
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* arch/arm/mach-ixp4xx/include/mach/cpu.h
*
* IXP4XX cpu type detection * IXP4XX cpu type detection
* *
* Copyright (C) 2007 MontaVista Software, Inc. * Copyright (C) 2007 MontaVista Software, Inc.
*/ */
#ifndef __ASM_ARCH_CPU_H__ #ifndef __SOC_IXP4XX_CPU_H__
#define __ASM_ARCH_CPU_H__ #define __SOC_IXP4XX_CPU_H__
#include <linux/io.h> #include <linux/io.h>
#ifdef CONFIG_ARM
#include <asm/cputype.h> #include <asm/cputype.h>
#endif
/* Processor id value in CP15 Register 0 */ /* Processor id value in CP15 Register 0 */
#define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */ #define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */
...@@ -23,6 +23,61 @@ ...@@ -23,6 +23,61 @@
#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */ #define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
#define IXP46X_PROCESSOR_ID_MASK 0xfffffff0 #define IXP46X_PROCESSOR_ID_MASK 0xfffffff0
/* "fuse" bits of IXP_EXP_CFG2 */
/* All IXP4xx CPUs */
#define IXP4XX_FEATURE_RCOMP (1 << 0)
#define IXP4XX_FEATURE_USB_DEVICE (1 << 1)
#define IXP4XX_FEATURE_HASH (1 << 2)
#define IXP4XX_FEATURE_AES (1 << 3)
#define IXP4XX_FEATURE_DES (1 << 4)
#define IXP4XX_FEATURE_HDLC (1 << 5)
#define IXP4XX_FEATURE_AAL (1 << 6)
#define IXP4XX_FEATURE_HSS (1 << 7)
#define IXP4XX_FEATURE_UTOPIA (1 << 8)
#define IXP4XX_FEATURE_NPEB_ETH0 (1 << 9)
#define IXP4XX_FEATURE_NPEC_ETH (1 << 10)
#define IXP4XX_FEATURE_RESET_NPEA (1 << 11)
#define IXP4XX_FEATURE_RESET_NPEB (1 << 12)
#define IXP4XX_FEATURE_RESET_NPEC (1 << 13)
#define IXP4XX_FEATURE_PCI (1 << 14)
#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
#define IXP4XX_FEATURE_XSCALE_MAX_FREQ (3 << 22)
#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP | \
IXP4XX_FEATURE_USB_DEVICE | \
IXP4XX_FEATURE_HASH | \
IXP4XX_FEATURE_AES | \
IXP4XX_FEATURE_DES | \
IXP4XX_FEATURE_HDLC | \
IXP4XX_FEATURE_AAL | \
IXP4XX_FEATURE_HSS | \
IXP4XX_FEATURE_UTOPIA | \
IXP4XX_FEATURE_NPEB_ETH0 | \
IXP4XX_FEATURE_NPEC_ETH | \
IXP4XX_FEATURE_RESET_NPEA | \
IXP4XX_FEATURE_RESET_NPEB | \
IXP4XX_FEATURE_RESET_NPEC | \
IXP4XX_FEATURE_PCI | \
IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
IXP4XX_FEATURE_XSCALE_MAX_FREQ)
/* IXP43x/46x CPUs */
#define IXP4XX_FEATURE_ECC_TIMESYNC (1 << 15)
#define IXP4XX_FEATURE_USB_HOST (1 << 18)
#define IXP4XX_FEATURE_NPEA_ETH (1 << 19)
#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK | \
IXP4XX_FEATURE_ECC_TIMESYNC | \
IXP4XX_FEATURE_USB_HOST | \
IXP4XX_FEATURE_NPEA_ETH)
/* IXP46x CPU (including IXP455) only */
#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3 (1 << 20)
#define IXP4XX_FEATURE_RSA (1 << 21)
#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK | \
IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \
IXP4XX_FEATURE_RSA)
#ifdef CONFIG_ARCH_IXP4XX
#define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP42X_PROCESSOR_ID_MASK | 0xF)) == \ #define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP42X_PROCESSOR_ID_MASK | 0xF)) == \
IXP42X_PROCESSOR_ID_VALUE) IXP42X_PROCESSOR_ID_VALUE)
#define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \ #define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
...@@ -32,23 +87,20 @@ ...@@ -32,23 +87,20 @@
#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \ #define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
IXP46X_PROCESSOR_ID_VALUE) IXP46X_PROCESSOR_ID_VALUE)
u32 ixp4xx_read_feature_bits(void);
void ixp4xx_write_feature_bits(u32 value);
#else
#define cpu_is_ixp42x_rev_a0() 0
#define cpu_is_ixp42x() 0
#define cpu_is_ixp43x() 0
#define cpu_is_ixp46x() 0
static inline u32 ixp4xx_read_feature_bits(void) static inline u32 ixp4xx_read_feature_bits(void)
{ {
u32 val = ~__raw_readl(IXP4XX_EXP_CFG2); return 0;
if (cpu_is_ixp42x_rev_a0())
return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
IXP4XX_FEATURE_AES);
if (cpu_is_ixp42x())
return val & IXP42X_FEATURE_MASK;
if (cpu_is_ixp43x())
return val & IXP43X_FEATURE_MASK;
return val & IXP46X_FEATURE_MASK;
} }
static inline void ixp4xx_write_feature_bits(u32 value) static inline void ixp4xx_write_feature_bits(u32 value)
{ {
__raw_writel(~value, IXP4XX_EXP_CFG2);
} }
#endif
#endif /* _ASM_ARCH_CPU_H */ #endif /* _ASM_ARCH_CPU_H */
...@@ -611,12 +611,6 @@ ...@@ -611,12 +611,6 @@
#define EXYNOS5420_FSYS2_OPTION 0x4168 #define EXYNOS5420_FSYS2_OPTION 0x4168
#define EXYNOS5420_PSGEN_OPTION 0x4188 #define EXYNOS5420_PSGEN_OPTION 0x4188
/* For EXYNOS_CENTRAL_SEQ_OPTION */
#define EXYNOS5_USE_STANDBYWFI_ARM_CORE0 BIT(16)
#define EXYNOS5_USE_STANDBYWFI_ARM_CORE1 BUT(17)
#define EXYNOS5_USE_STANDBYWFE_ARM_CORE0 BIT(24)
#define EXYNOS5_USE_STANDBYWFE_ARM_CORE1 BIT(25)
#define EXYNOS5420_ARM_USE_STANDBY_WFI0 BIT(4) #define EXYNOS5420_ARM_USE_STANDBY_WFI0 BIT(4)
#define EXYNOS5420_ARM_USE_STANDBY_WFI1 BIT(5) #define EXYNOS5420_ARM_USE_STANDBY_WFI1 BIT(5)
#define EXYNOS5420_ARM_USE_STANDBY_WFI2 BIT(6) #define EXYNOS5420_ARM_USE_STANDBY_WFI2 BIT(6)
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define MXC_CPU_MX27 27 #define MXC_CPU_MX27 27
#define MXC_CPU_MX31 31 #define MXC_CPU_MX31 31
#define MXC_CPU_MX35 35 #define MXC_CPU_MX35 35
#define MXC_CPU_MX50 50
#define MXC_CPU_MX51 51 #define MXC_CPU_MX51 51
#define MXC_CPU_MX53 53 #define MXC_CPU_MX53 53
#define MXC_CPU_IMX6SL 0x60 #define MXC_CPU_IMX6SL 0x60
......
...@@ -6,6 +6,37 @@ ...@@ -6,6 +6,37 @@
#ifndef __SOC_TEGRA_COMMON_H__ #ifndef __SOC_TEGRA_COMMON_H__
#define __SOC_TEGRA_COMMON_H__ #define __SOC_TEGRA_COMMON_H__
#include <linux/errno.h>
#include <linux/types.h>
struct device;
/**
* Tegra SoC core device OPP table configuration
*
* @init_state: pre-initialize OPP state of a device
*/
struct tegra_core_opp_params {
bool init_state;
};
#ifdef CONFIG_ARCH_TEGRA
bool soc_is_tegra(void); bool soc_is_tegra(void);
int devm_tegra_core_dev_init_opp_table(struct device *dev,
struct tegra_core_opp_params *params);
#else
static inline bool soc_is_tegra(void)
{
return false;
}
static inline int
devm_tegra_core_dev_init_opp_table(struct device *dev,
struct tegra_core_opp_params *params)
{
return -ENODEV;
}
#endif
#endif /* __SOC_TEGRA_COMMON_H__ */ #endif /* __SOC_TEGRA_COMMON_H__ */
...@@ -52,14 +52,28 @@ struct tegra_sku_info { ...@@ -52,14 +52,28 @@ struct tegra_sku_info {
enum tegra_revision revision; enum tegra_revision revision;
}; };
#ifdef CONFIG_ARCH_TEGRA
extern struct tegra_sku_info tegra_sku_info;
u32 tegra_read_straps(void); u32 tegra_read_straps(void);
u32 tegra_read_ram_code(void); u32 tegra_read_ram_code(void);
int tegra_fuse_readl(unsigned long offset, u32 *value); int tegra_fuse_readl(unsigned long offset, u32 *value);
#ifdef CONFIG_ARCH_TEGRA
extern struct tegra_sku_info tegra_sku_info;
#else #else
static struct tegra_sku_info tegra_sku_info __maybe_unused; static struct tegra_sku_info tegra_sku_info __maybe_unused;
static inline u32 tegra_read_straps(void)
{
return 0;
}
static inline u32 tegra_read_ram_code(void)
{
return 0;
}
static inline int tegra_fuse_readl(unsigned long offset, u32 *value)
{
return -ENODEV;
}
#endif #endif
struct device *tegra_soc_device_register(void); struct device *tegra_soc_device_register(void);
......
...@@ -171,6 +171,8 @@ int tegra_io_rail_power_off(unsigned int id); ...@@ -171,6 +171,8 @@ int tegra_io_rail_power_off(unsigned int id);
void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode);
void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode); void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode);
bool tegra_pmc_core_domain_state_synced(void);
#else #else
static inline int tegra_powergate_power_on(unsigned int id) static inline int tegra_powergate_power_on(unsigned int id)
{ {
...@@ -227,6 +229,11 @@ static inline void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode) ...@@ -227,6 +229,11 @@ static inline void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode)
{ {
} }
static inline bool tegra_pmc_core_domain_state_synced(void)
{
return false;
}
#endif /* CONFIG_SOC_TEGRA_PMC */ #endif /* CONFIG_SOC_TEGRA_PMC */
#if defined(CONFIG_SOC_TEGRA_PMC) && defined(CONFIG_PM_SLEEP) #if defined(CONFIG_SOC_TEGRA_PMC) && defined(CONFIG_PM_SLEEP)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment