mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-08 14:13:53 +00:00
ARM: SoC updates
The code changes are mostly for 32-bit platforms and include: - Lots of updates for the Nvidia Tegra platform, including cpuidle, pmc, and dt-binding changes - Microchip at91 power management updates for the recently added sam9x60 SoC - Treewide setup_irq deprecation by afzal mohammed - STMicroelectronics stm32 gains earlycon support - Renesas platforms with Cortex-A9 can now use the global timer - Some TI OMAP2+ platforms gain cpuidle support - Various cleanups for the i.MX6 and Orion platforms, as well as Kconfig files across all platforms Signed-off-by: Arnd Bergmann <arnd@arndb.de> -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAl6EaLsACgkQmmx57+YA GNkg/Q/9EmLGT/bznqi6P/8V75qPY6j4swife5HlI43EdCEyN+iME1w1rFfrNilf A/QyXzxhYgUZoyIt7K4qjWc8fPNlJZ8X10UqeEftQFxi82cmX2+OaT2fy6OdHVRJ SAGb1pw7463TQ6LKA7LC7rztFjahsjnE/9szlgXQT4v5OzayGyxd3OKy2Q1zASEi rwN+85Lh+xJvWhhenPKVvs2Dei+up8Y9uyPfJkj2QudCB+zx5k5stkk4EiQLBd1W SHzhijbSU3MrAUz2Cnp9Qa+86DdGPvFPfpzQy3pSYU9nNrC0aKpS8YmHT99SIWVN 6R1YJF7Htmui5I9+O0baejJMEqvzGUysqe+rQdCofD7ooVKWU7WKYj5HxZxyBCEN dvlN3KRmS6l5KLsZARSxuBUw2MPTgjsxczZ84NKMLj8czw6yXyrePZ1RWiEZ4HIu 4GiFNLYSMmAynD/dLuC9USDsjlPsQKnQ3e8hDf3a6oK5OHUIkr3uvguhqWa5WJsi cy2DUeWJkXgJDhlxcfr8MiPpPJRo3N/8O8PYci8dkdDFRs32j/5Qf22vywDdUHaZ I9Pl+VOGOSGiqRc9gmay6DNXpJusfuv72omrz4rL4kGMahpk0LeV5w+a9TdrkreY sLM67wtshOjOVMc/ebQ5Q8RR17Go+MFK+Co9Yc1ybbQ6lkSzeuY= =UTk1 -----END PGP SIGNATURE----- Merge tag 'arm-soc-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc Pull ARM SoC updates from Arnd Bergmann: "The code changes are mostly for 32-bit platforms and include: - Lots of updates for the Nvidia Tegra platform, including cpuidle, pmc, and dt-binding changes - Microchip at91 power management updates for the recently added sam9x60 SoC - Treewide setup_irq deprecation by afzal mohammed - STMicroelectronics stm32 gains earlycon support - Renesas platforms with Cortex-A9 can now use the global timer - Some TI OMAP2+ platforms gain cpuidle support - Various cleanups for the i.MX6 and Orion platforms, as well as Kconfig files across all platforms" * tag 'arm-soc-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (75 commits) ARM: qcom: Add support for IPQ40xx ARM: mmp: replace setup_irq() by request_irq() ARM: cns3xxx: replace setup_irq() by request_irq() ARM: spear: replace setup_irq() by request_irq() ARM: ep93xx: Replace setup_irq() by request_irq() ARM: iop32x: replace setup_irq() by request_irq() arm: mach-dove: Mark dove_io_desc as __maybe_unused ARM: orion: replace setup_irq() by request_irq() ARM: debug: stm32: add UART early console support for STM32MP1 ARM: debug: stm32: add UART early console support for STM32H7 ARM: debug: stm32: add UART early console configuration for STM32F7 ARM: debug: stm32: add UART early console configuration for STM32F4 cpuidle: tegra: Disable CC6 state if LP2 unavailable cpuidle: tegra: Squash Tegra114 driver into the common driver cpuidle: tegra: Squash Tegra30 driver into the common driver cpuidle: Refactor and move out NVIDIA Tegra20 driver into drivers/cpuidle ARM: tegra: cpuidle: Remove unnecessary memory barrier ARM: tegra: cpuidle: Make abort_flag atomic ARM: tegra: cpuidle: Handle case where secondary CPU hangs on entering LP2 ARM: tegra: Make outer_disable() open-coded ...
This commit is contained in:
commit
0e8fb69f28
@ -212,6 +212,8 @@ properties:
|
||||
- rockchip,rk3066-smp
|
||||
- socionext,milbeaut-m10v-smp
|
||||
- ste,dbx500-smp
|
||||
- ti,am3352
|
||||
- ti,am4372
|
||||
|
||||
cpu-release-addr:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint64'
|
||||
|
@ -1,300 +0,0 @@
|
||||
NVIDIA Tegra Power Management Controller (PMC)
|
||||
|
||||
== Power Management Controller Node ==
|
||||
|
||||
The PMC block interacts with an external Power Management Unit. The PMC
|
||||
mostly controls the entry and exit of the system from different sleep
|
||||
modes. It provides power-gating controllers for SoC and CPU power-islands.
|
||||
|
||||
Required properties:
|
||||
- name : Should be pmc
|
||||
- compatible : Should contain one of the following:
|
||||
For Tegra20 must contain "nvidia,tegra20-pmc".
|
||||
For Tegra30 must contain "nvidia,tegra30-pmc".
|
||||
For Tegra114 must contain "nvidia,tegra114-pmc"
|
||||
For Tegra124 must contain "nvidia,tegra124-pmc"
|
||||
For Tegra132 must contain "nvidia,tegra124-pmc"
|
||||
For Tegra210 must contain "nvidia,tegra210-pmc"
|
||||
- reg : Offset and length of the register set for the device
|
||||
- clocks : Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names : Must include the following entries:
|
||||
"pclk" (The Tegra clock of that name),
|
||||
"clk32k_in" (The 32KHz clock input to Tegra).
|
||||
|
||||
Optional properties:
|
||||
- nvidia,invert-interrupt : If present, inverts the PMU interrupt signal.
|
||||
The PMU is an external Power Management Unit, whose interrupt output
|
||||
signal is fed into the PMC. This signal is optionally inverted, and then
|
||||
fed into the ARM GIC. The PMC is not involved in the detection or
|
||||
handling of this interrupt signal, merely its inversion.
|
||||
- nvidia,suspend-mode : The suspend mode that the platform should use.
|
||||
Valid values are 0, 1 and 2:
|
||||
0 (LP0): CPU + Core voltage off and DRAM in self-refresh
|
||||
1 (LP1): CPU voltage off and DRAM in self-refresh
|
||||
2 (LP2): CPU voltage off
|
||||
- nvidia,core-power-req-active-high : Boolean, core power request active-high
|
||||
- nvidia,sys-clock-req-active-high : Boolean, system clock request active-high
|
||||
- nvidia,combined-power-req : Boolean, combined power request for CPU & Core
|
||||
- nvidia,cpu-pwr-good-en : Boolean, CPU power good signal (from PMIC to PMC)
|
||||
is enabled.
|
||||
|
||||
Required properties when nvidia,suspend-mode is specified:
|
||||
- nvidia,cpu-pwr-good-time : CPU power good time in uS.
|
||||
- nvidia,cpu-pwr-off-time : CPU power off time in uS.
|
||||
- nvidia,core-pwr-good-time : <Oscillator-stable-time Power-stable-time>
|
||||
Core power good time in uS.
|
||||
- nvidia,core-pwr-off-time : Core power off time in uS.
|
||||
|
||||
Required properties when nvidia,suspend-mode=<0>:
|
||||
- nvidia,lp0-vec : <start length> Starting address and length of LP0 vector
|
||||
The LP0 vector contains the warm boot code that is executed by AVP when
|
||||
resuming from the LP0 state. The AVP (Audio-Video Processor) is an ARM7
|
||||
processor and always being the first boot processor when chip is power on
|
||||
or resume from deep sleep mode. When the system is resumed from the deep
|
||||
sleep mode, the warm boot code will restore some PLLs, clocks and then
|
||||
bring up CPU0 for resuming the system.
|
||||
|
||||
Hardware-triggered thermal reset:
|
||||
On Tegra30, Tegra114 and Tegra124, if the 'i2c-thermtrip' subnode exists,
|
||||
hardware-triggered thermal reset will be enabled.
|
||||
|
||||
Required properties for hardware-triggered thermal reset (inside 'i2c-thermtrip'):
|
||||
- nvidia,i2c-controller-id : ID of I2C controller to send poweroff command to. Valid values are
|
||||
described in section 9.2.148 "APBDEV_PMC_SCRATCH53_0" of the
|
||||
Tegra K1 Technical Reference Manual.
|
||||
- nvidia,bus-addr : Bus address of the PMU on the I2C bus
|
||||
- nvidia,reg-addr : I2C register address to write poweroff command to
|
||||
- nvidia,reg-data : Poweroff command to write to PMU
|
||||
|
||||
Optional properties for hardware-triggered thermal reset (inside 'i2c-thermtrip'):
|
||||
- nvidia,pinmux-id : Pinmux used by the hardware when issuing poweroff command.
|
||||
Defaults to 0. Valid values are described in section 12.5.2
|
||||
"Pinmux Support" of the Tegra4 Technical Reference Manual.
|
||||
|
||||
Optional nodes:
|
||||
- powergates : This node contains a hierarchy of power domain nodes, which
|
||||
should match the powergates on the Tegra SoC. See "Powergate
|
||||
Nodes" below.
|
||||
|
||||
Example:
|
||||
|
||||
/ SoC dts including file
|
||||
pmc@7000f400 {
|
||||
compatible = "nvidia,tegra20-pmc";
|
||||
reg = <0x7000e400 0x400>;
|
||||
clocks = <&tegra_car 110>, <&clk32k_in>;
|
||||
clock-names = "pclk", "clk32k_in";
|
||||
nvidia,invert-interrupt;
|
||||
nvidia,suspend-mode = <1>;
|
||||
nvidia,cpu-pwr-good-time = <2000>;
|
||||
nvidia,cpu-pwr-off-time = <100>;
|
||||
nvidia,core-pwr-good-time = <3845 3845>;
|
||||
nvidia,core-pwr-off-time = <458>;
|
||||
nvidia,core-power-req-active-high;
|
||||
nvidia,sys-clock-req-active-high;
|
||||
nvidia,lp0-vec = <0xbdffd000 0x2000>;
|
||||
};
|
||||
|
||||
/ Tegra board dts file
|
||||
{
|
||||
...
|
||||
pmc@7000f400 {
|
||||
i2c-thermtrip {
|
||||
nvidia,i2c-controller-id = <4>;
|
||||
nvidia,bus-addr = <0x40>;
|
||||
nvidia,reg-addr = <0x36>;
|
||||
nvidia,reg-data = <0x2>;
|
||||
};
|
||||
};
|
||||
...
|
||||
clocks {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
clk32k_in: clock {
|
||||
compatible = "fixed-clock";
|
||||
reg=<0>;
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
};
|
||||
};
|
||||
...
|
||||
};
|
||||
|
||||
|
||||
== Powergate Nodes ==
|
||||
|
||||
Each of the powergate nodes represents a power-domain on the Tegra SoC
|
||||
that can be power-gated by the Tegra PMC. The name of the powergate node
|
||||
should be one of the below. Note that not every powergate is applicable
|
||||
to all Tegra devices and the following list shows which powergates are
|
||||
applicable to which devices. Please refer to the Tegra TRM for more
|
||||
details on the various powergates.
|
||||
|
||||
Name Description Devices Applicable
|
||||
3d 3D Graphics Tegra20/114/124/210
|
||||
3d0 3D Graphics 0 Tegra30
|
||||
3d1 3D Graphics 1 Tegra30
|
||||
aud Audio Tegra210
|
||||
dfd Debug Tegra210
|
||||
dis Display A Tegra114/124/210
|
||||
disb Display B Tegra114/124/210
|
||||
heg 2D Graphics Tegra30/114/124/210
|
||||
iram Internal RAM Tegra124/210
|
||||
mpe MPEG Encode All
|
||||
nvdec NVIDIA Video Decode Engine Tegra210
|
||||
nvjpg NVIDIA JPEG Engine Tegra210
|
||||
pcie PCIE Tegra20/30/124/210
|
||||
sata SATA Tegra30/124/210
|
||||
sor Display interfaces Tegra124/210
|
||||
ve2 Video Encode Engine 2 Tegra210
|
||||
venc Video Encode Engine All
|
||||
vdec Video Decode Engine Tegra20/30/114/124
|
||||
vic Video Imaging Compositor Tegra124/210
|
||||
xusba USB Partition A Tegra114/124/210
|
||||
xusbb USB Partition B Tegra114/124/210
|
||||
xusbc USB Partition C Tegra114/124/210
|
||||
|
||||
Required properties:
|
||||
- clocks: Must contain an entry for each clock required by the PMC for
|
||||
controlling a power-gate. See ../clocks/clock-bindings.txt for details.
|
||||
- resets: Must contain an entry for each reset required by the PMC for
|
||||
controlling a power-gate. See ../reset/reset.txt for details.
|
||||
- #power-domain-cells: Must be 0.
|
||||
|
||||
Example:
|
||||
|
||||
pmc: pmc@7000e400 {
|
||||
compatible = "nvidia,tegra210-pmc";
|
||||
reg = <0x0 0x7000e400 0x0 0x400>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
|
||||
clock-names = "pclk", "clk32k_in";
|
||||
|
||||
powergates {
|
||||
pd_audio: aud {
|
||||
clocks = <&tegra_car TEGRA210_CLK_APE>,
|
||||
<&tegra_car TEGRA210_CLK_APB2APE>;
|
||||
resets = <&tegra_car 198>;
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
== Powergate Clients ==
|
||||
|
||||
Hardware blocks belonging to a power domain should contain a "power-domains"
|
||||
property that is a phandle pointing to the corresponding powergate node.
|
||||
|
||||
Example:
|
||||
|
||||
adma: adma@702e2000 {
|
||||
...
|
||||
power-domains = <&pd_audio>;
|
||||
...
|
||||
};
|
||||
|
||||
== Pad Control ==
|
||||
|
||||
On Tegra SoCs a pad is a set of pins which are configured as a group.
|
||||
The pin grouping is a fixed attribute of the hardware. The PMC can be
|
||||
used to set pad power state and signaling voltage. A pad can be either
|
||||
in active or power down mode. The support for power state and signaling
|
||||
voltage configuration varies depending on the pad in question. 3.3 V and
|
||||
1.8 V signaling voltages are supported on pins where software
|
||||
controllable signaling voltage switching is available.
|
||||
|
||||
The pad configuration state nodes are placed under the pmc node and they
|
||||
are referred to by the pinctrl client properties. For more information
|
||||
see Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt.
|
||||
The pad name should be used as the value of the pins property in pin
|
||||
configuration nodes.
|
||||
|
||||
The following pads are present on Tegra124 and Tegra132:
|
||||
audio bb cam comp
|
||||
csia csb cse dsi
|
||||
dsib dsic dsid hdmi
|
||||
hsic hv lvds mipi-bias
|
||||
nand pex-bias pex-clk1 pex-clk2
|
||||
pex-cntrl sdmmc1 sdmmc3 sdmmc4
|
||||
sys_ddc uart usb0 usb1
|
||||
usb2 usb_bias
|
||||
|
||||
The following pads are present on Tegra210:
|
||||
audio audio-hv cam csia
|
||||
csib csic csid csie
|
||||
csif dbg debug-nonao dmic
|
||||
dp dsi dsib dsic
|
||||
dsid emmc emmc2 gpio
|
||||
hdmi hsic lvds mipi-bias
|
||||
pex-bias pex-clk1 pex-clk2 pex-cntrl
|
||||
sdmmc1 sdmmc3 spi spi-hv
|
||||
uart usb0 usb1 usb2
|
||||
usb3 usb-bias
|
||||
|
||||
Required pin configuration properties:
|
||||
- pins: Must contain name of the pad(s) to be configured.
|
||||
|
||||
Optional pin configuration properties:
|
||||
- low-power-enable: Configure the pad into power down mode
|
||||
- low-power-disable: Configure the pad into active mode
|
||||
- power-source: Must contain either TEGRA_IO_PAD_VOLTAGE_1V8
|
||||
or TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages.
|
||||
The values are defined in
|
||||
include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h.
|
||||
|
||||
Note: The power state can be configured on all of the Tegra124 and
|
||||
Tegra132 pads. None of the Tegra124 or Tegra132 pads support
|
||||
signaling voltage switching.
|
||||
|
||||
Note: All of the listed Tegra210 pads except pex-cntrl support power
|
||||
state configuration. Signaling voltage switching is supported on
|
||||
following Tegra210 pads: audio, audio-hv, cam, dbg, dmic, gpio,
|
||||
pex-cntrl, sdmmc1, sdmmc3, spi, spi-hv, and uart.
|
||||
|
||||
Pad configuration state example:
|
||||
pmc: pmc@7000e400 {
|
||||
compatible = "nvidia,tegra210-pmc";
|
||||
reg = <0x0 0x7000e400 0x0 0x400>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
|
||||
clock-names = "pclk", "clk32k_in";
|
||||
|
||||
...
|
||||
|
||||
sdmmc1_3v3: sdmmc1-3v3 {
|
||||
pins = "sdmmc1";
|
||||
power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>;
|
||||
};
|
||||
|
||||
sdmmc1_1v8: sdmmc1-1v8 {
|
||||
pins = "sdmmc1";
|
||||
power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
|
||||
};
|
||||
|
||||
hdmi_off: hdmi-off {
|
||||
pins = "hdmi";
|
||||
low-power-enable;
|
||||
}
|
||||
|
||||
hdmi_on: hdmi-on {
|
||||
pins = "hdmi";
|
||||
low-power-disable;
|
||||
}
|
||||
};
|
||||
|
||||
Pinctrl client example:
|
||||
sdmmc1: sdhci@700b0000 {
|
||||
...
|
||||
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
|
||||
pinctrl-0 = <&sdmmc1_3v3>;
|
||||
pinctrl-1 = <&sdmmc1_1v8>;
|
||||
};
|
||||
...
|
||||
sor@54540000 {
|
||||
...
|
||||
pinctrl-0 = <&hdmi_off>;
|
||||
pinctrl-1 = <&hdmi_on>;
|
||||
pinctrl-names = "hdmi-on", "hdmi-off";
|
||||
};
|
@ -0,0 +1,354 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/arm/tegra/nvidia,tegra20-pmc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Tegra Power Management Controller (PMC)
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jonathan Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra20-pmc
|
||||
- nvidia,tegra20-pmc
|
||||
- nvidia,tegra30-pmc
|
||||
- nvidia,tegra114-pmc
|
||||
- nvidia,tegra124-pmc
|
||||
- nvidia,tegra210-pmc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description:
|
||||
Offset and length of the register set for the device.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: clk32k_in
|
||||
description:
|
||||
Must includes entries pclk and clk32k_in.
|
||||
pclk is the Tegra clock of that name and clk32k_in is 32KHz clock
|
||||
input to Tegra.
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
description:
|
||||
Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clocks-bindings.txt for details.
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
description:
|
||||
Tegra PMC has clk_out_1, clk_out_2, and clk_out_3.
|
||||
PMC also has blink control which allows 32Khz clock output to
|
||||
Tegra blink pad.
|
||||
Consumer of PMC clock should specify the desired clock by having
|
||||
the clock ID in its "clocks" phandle cell with pmc clock provider.
|
||||
See include/dt-bindings/soc/tegra-pmc.h for the list of Tegra PMC
|
||||
clock IDs.
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 2
|
||||
description:
|
||||
Specifies number of cells needed to encode an interrupt source.
|
||||
The value must be 2.
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
nvidia,invert-interrupt:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: Inverts the PMU interrupt signal.
|
||||
The PMU is an external Power Management Unit, whose interrupt output
|
||||
signal is fed into the PMC. This signal is optionally inverted, and
|
||||
then fed into the ARM GIC. The PMC is not involved in the detection
|
||||
or handling of this interrupt signal, merely its inversion.
|
||||
|
||||
nvidia,core-power-req-active-high:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: Core power request active-high.
|
||||
|
||||
nvidia,sys-clock-req-active-high:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: System clock request active-high.
|
||||
|
||||
nvidia,combined-power-req:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: combined power request for CPU and Core.
|
||||
|
||||
nvidia,cpu-pwr-good-en:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
CPU power good signal from external PMIC to PMC is enabled.
|
||||
|
||||
nvidia,suspend-mode:
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/uint32
|
||||
- enum: [0, 1, 2]
|
||||
description:
|
||||
The suspend mode that the platform should use.
|
||||
Mode 0 is for LP0, CPU + Core voltage off and DRAM in self-refresh
|
||||
Mode 1 is for LP1, CPU voltage off and DRAM in self-refresh
|
||||
Mode 2 is for LP2, CPU voltage off
|
||||
|
||||
nvidia,cpu-pwr-good-time:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: CPU power good time in uSec.
|
||||
|
||||
nvidia,cpu-pwr-off-time:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: CPU power off time in uSec.
|
||||
|
||||
nvidia,core-pwr-good-time:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
<Oscillator-stable-time Power-stable-time>
|
||||
Core power good time in uSec.
|
||||
|
||||
nvidia,core-pwr-off-time:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Core power off time in uSec.
|
||||
|
||||
nvidia,lp0-vec:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
<start length> Starting address and length of LP0 vector.
|
||||
The LP0 vector contains the warm boot code that is executed
|
||||
by AVP when resuming from the LP0 state.
|
||||
The AVP (Audio-Video Processor) is an ARM7 processor and
|
||||
always being the first boot processor when chip is power on
|
||||
or resume from deep sleep mode. When the system is resumed
|
||||
from the deep sleep mode, the warm boot code will restore
|
||||
some PLLs, clocks and then brings up CPU0 for resuming the
|
||||
system.
|
||||
|
||||
i2c-thermtrip:
|
||||
type: object
|
||||
description:
|
||||
On Tegra30, Tegra114 and Tegra124 if i2c-thermtrip subnode exists,
|
||||
hardware-triggered thermal reset will be enabled.
|
||||
|
||||
properties:
|
||||
nvidia,i2c-controller-id:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
ID of I2C controller to send poweroff command to PMU.
|
||||
Valid values are described in section 9.2.148
|
||||
"APBDEV_PMC_SCRATCH53_0" of the Tegra K1 Technical Reference
|
||||
Manual.
|
||||
|
||||
nvidia,bus-addr:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Bus address of the PMU on the I2C bus.
|
||||
|
||||
nvidia,reg-addr:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: PMU I2C register address to issue poweroff command.
|
||||
|
||||
nvidia,reg-data:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Poweroff command to write to PMU.
|
||||
|
||||
nvidia,pinmux-id:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Pinmux used by the hardware when issuing Poweroff command.
|
||||
Defaults to 0. Valid values are described in section 12.5.2
|
||||
"Pinmux Support" of the Tegra4 Technical Reference Manual.
|
||||
|
||||
required:
|
||||
- nvidia,i2c-controller-id
|
||||
- nvidia,bus-addr
|
||||
- nvidia,reg-addr
|
||||
- nvidia,reg-data
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
powergates:
|
||||
type: object
|
||||
description: |
|
||||
This node contains a hierarchy of power domain nodes, which should
|
||||
match the powergates on the Tegra SoC. Each powergate node
|
||||
represents a power-domain on the Tegra SoC that can be power-gated
|
||||
by the Tegra PMC.
|
||||
Hardware blocks belonging to a power domain should contain
|
||||
"power-domains" property that is a phandle pointing to corresponding
|
||||
powergate node.
|
||||
The name of the powergate node should be one of the below. Note that
|
||||
not every powergate is applicable to all Tegra devices and the following
|
||||
list shows which powergates are applicable to which devices.
|
||||
Please refer to Tegra TRM for mode details on the powergate nodes to
|
||||
use for each power-gate block inside Tegra.
|
||||
Name Description Devices Applicable
|
||||
3d 3D Graphics Tegra20/114/124/210
|
||||
3d0 3D Graphics 0 Tegra30
|
||||
3d1 3D Graphics 1 Tegra30
|
||||
aud Audio Tegra210
|
||||
dfd Debug Tegra210
|
||||
dis Display A Tegra114/124/210
|
||||
disb Display B Tegra114/124/210
|
||||
heg 2D Graphics Tegra30/114/124/210
|
||||
iram Internal RAM Tegra124/210
|
||||
mpe MPEG Encode All
|
||||
nvdec NVIDIA Video Decode Engine Tegra210
|
||||
nvjpg NVIDIA JPEG Engine Tegra210
|
||||
pcie PCIE Tegra20/30/124/210
|
||||
sata SATA Tegra30/124/210
|
||||
sor Display interfaces Tegra124/210
|
||||
ve2 Video Encode Engine 2 Tegra210
|
||||
venc Video Encode Engine All
|
||||
vdec Video Decode Engine Tegra20/30/114/124
|
||||
vic Video Imaging Compositor Tegra124/210
|
||||
xusba USB Partition A Tegra114/124/210
|
||||
xusbb USB Partition B Tegra114/124/210
|
||||
xusbc USB Partition C Tegra114/124/210
|
||||
|
||||
patternProperties:
|
||||
"^[a-z0-9]+$":
|
||||
type: object
|
||||
|
||||
patternProperties:
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
description:
|
||||
Must contain an entry for each clock required by the PMC
|
||||
for controlling a power-gate.
|
||||
See ../clocks/clock-bindings.txt document for more details.
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
description:
|
||||
Must contain an entry for each reset required by the PMC
|
||||
for controlling a power-gate.
|
||||
See ../reset/reset.txt for more details.
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 0
|
||||
description: Must be 0.
|
||||
|
||||
required:
|
||||
- clocks
|
||||
- resets
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
"^[a-f0-9]+-[a-f0-9]+$":
|
||||
type: object
|
||||
description:
|
||||
This is a Pad configuration node. On Tegra SOCs a pad is a set of
|
||||
pins which are configured as a group. The pin grouping is a fixed
|
||||
attribute of the hardware. The PMC can be used to set pad power state
|
||||
and signaling voltage. A pad can be either in active or power down mode.
|
||||
The support for power state and signaling voltage configuration varies
|
||||
depending on the pad in question. 3.3V and 1.8V signaling voltages
|
||||
are supported on pins where software controllable signaling voltage
|
||||
switching is available.
|
||||
|
||||
The pad configuration state nodes are placed under the pmc node and they
|
||||
are referred to by the pinctrl client properties. For more information
|
||||
see Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt.
|
||||
The pad name should be used as the value of the pins property in pin
|
||||
configuration nodes.
|
||||
|
||||
The following pads are present on Tegra124 and Tegra132
|
||||
audio, bb, cam, comp, csia, csb, cse, dsi, dsib, dsic, dsid, hdmi, hsic,
|
||||
hv, lvds, mipi-bias, nand, pex-bias, pex-clk1, pex-clk2, pex-cntrl,
|
||||
sdmmc1, sdmmc3, sdmmc4, sys_ddc, uart, usb0, usb1, usb2, usb_bias.
|
||||
|
||||
The following pads are present on Tegra210
|
||||
audio, audio-hv, cam, csia, csib, csic, csid, csie, csif, dbg,
|
||||
debug-nonao, dmic, dp, dsi, dsib, dsic, dsid, emmc, emmc2, gpio, hdmi,
|
||||
hsic, lvds, mipi-bias, pex-bias, pex-clk1, pex-clk2, pex-cntrl, sdmmc1,
|
||||
sdmmc3, spi, spi-hv, uart, usb0, usb1, usb2, usb3, usb-bias.
|
||||
|
||||
properties:
|
||||
pins:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: Must contain name of the pad(s) to be configured.
|
||||
|
||||
low-power-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: Configure the pad into power down mode.
|
||||
|
||||
low-power-disable:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: Configure the pad into active mode.
|
||||
|
||||
power-source:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Must contain either TEGRA_IO_PAD_VOLTAGE_1V8 or
|
||||
TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages.
|
||||
The values are defined in
|
||||
include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h.
|
||||
Power state can be configured on all Tegra124 and Tegra132
|
||||
pads. None of the Tegra124 or Tegra132 pads support signaling
|
||||
voltage switching.
|
||||
All of the listed Tegra210 pads except pex-cntrl support power
|
||||
state configuration. Signaling voltage switching is supported
|
||||
on below Tegra210 pads.
|
||||
audio, audio-hv, cam, dbg, dmic, gpio, pex-cntrl, sdmmc1,
|
||||
sdmmc3, spi, spi-hv, and uart.
|
||||
|
||||
required:
|
||||
- pins
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clock-names
|
||||
- clocks
|
||||
- '#clock-cells'
|
||||
|
||||
dependencies:
|
||||
"nvidia,suspend-mode": ["nvidia,core-pwr-off-time", "nvidia,cpu-pwr-off-time"]
|
||||
"nvidia,core-pwr-off-time": ["nvidia,core-pwr-good-time"]
|
||||
"nvidia,cpu-pwr-off-time": ["nvidia,cpu-pwr-good-time"]
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
#include <dt-bindings/clock/tegra210-car.h>
|
||||
#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
|
||||
#include <dt-bindings/soc/tegra-pmc.h>
|
||||
|
||||
tegra_pmc: pmc@7000e400 {
|
||||
compatible = "nvidia,tegra210-pmc";
|
||||
reg = <0x0 0x7000e400 0x0 0x400>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
|
||||
clock-names = "pclk", "clk32k_in";
|
||||
#clock-cells = <1>;
|
||||
|
||||
nvidia,invert-interrupt;
|
||||
nvidia,suspend-mode = <0>;
|
||||
nvidia,cpu-pwr-good-time = <0>;
|
||||
nvidia,cpu-pwr-off-time = <0>;
|
||||
nvidia,core-pwr-good-time = <4587 3876>;
|
||||
nvidia,core-pwr-off-time = <39065>;
|
||||
nvidia,core-power-req-active-high;
|
||||
nvidia,sys-clock-req-active-high;
|
||||
|
||||
powergates {
|
||||
pd_audio: aud {
|
||||
clocks = <&tegra_car TEGRA210_CLK_APE>,
|
||||
<&tegra_car TEGRA210_CLK_APB2APE>;
|
||||
resets = <&tegra_car 198>;
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
|
||||
pd_xusbss: xusba {
|
||||
clocks = <&tegra_car TEGRA210_CLK_XUSB_SS>;
|
||||
resets = <&tegra_car TEGRA210_CLK_XUSB_SS>;
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
@ -37,6 +37,7 @@ Required properties:
|
||||
- Tegra132: "nvidia,tegra132-xusb-padctl", "nvidia,tegra124-xusb-padctl"
|
||||
- Tegra210: "nvidia,tegra210-xusb-padctl"
|
||||
- Tegra186: "nvidia,tegra186-xusb-padctl"
|
||||
- Tegra194: "nvidia,tegra194-xusb-padctl"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
- reset-names: Must include the following entries:
|
||||
@ -62,6 +63,10 @@ For Tegra186:
|
||||
- vclamp-usb-supply: Bias rail for USB pad. Must supply 1.8 V.
|
||||
- vddio-hsic-supply: HSIC PHY power supply. Must supply 1.2 V.
|
||||
|
||||
For Tegra194:
|
||||
- avdd-usb-supply: USB I/Os, VBUS, ID, REXT, D+/D- power supply. Must supply
|
||||
3.3 V.
|
||||
- vclamp-usb-supply: Bias rail for USB pad. Must supply 1.8 V.
|
||||
|
||||
Pad nodes:
|
||||
==========
|
||||
@ -154,6 +159,11 @@ For Tegra210, the list of valid PHY nodes is given below:
|
||||
- sata: sata-0
|
||||
- functions: "usb3-ss", "sata"
|
||||
|
||||
For Tegra194, the list of valid PHY nodes is given below:
|
||||
- usb2: usb2-0, usb2-1, usb2-2, usb2-3
|
||||
- functions: "xusb"
|
||||
- usb3: usb3-0, usb3-1, usb3-2, usb3-3
|
||||
- functions: "xusb"
|
||||
|
||||
Port nodes:
|
||||
===========
|
||||
@ -174,6 +184,12 @@ Required properties:
|
||||
- "device": for USB device mode
|
||||
- "otg": for USB OTG mode
|
||||
|
||||
Required properties for OTG/Peripheral capable USB2 ports:
|
||||
- usb-role-switch: Boolean property to indicate that the port support OTG or
|
||||
peripheral mode. If present, the port supports switching between USB host
|
||||
and peripheral roles. Connector should be added as subnode.
|
||||
See usb/usb-conn-gpio.txt.
|
||||
|
||||
Optional properties:
|
||||
- nvidia,internal: A boolean property whose presence determines that a port
|
||||
is internal. In the absence of this property the port is considered to be
|
||||
@ -221,6 +237,11 @@ Optional properties:
|
||||
is internal. In the absence of this property the port is considered to be
|
||||
external.
|
||||
|
||||
- maximum-speed: Only for Tegra194. A string property that specifies maximum
|
||||
supported speed of a usb3 port. Valid values are:
|
||||
- "super-speed-plus": default, the usb3 port supports USB 3.1 Gen 2 speed.
|
||||
- "super-speed": the usb3 port supports USB 3.1 Gen 1 speed only.
|
||||
|
||||
For Tegra124 and Tegra132, the XUSB pad controller exposes the following
|
||||
ports:
|
||||
- 3x USB2: usb2-0, usb2-1, usb2-2
|
||||
@ -233,6 +254,9 @@ For Tegra210, the XUSB pad controller exposes the following ports:
|
||||
- 2x HSIC: hsic-0, hsic-1
|
||||
- 4x super-speed USB: usb3-0, usb3-1, usb3-2, usb3-3
|
||||
|
||||
For Tegra194, the XUSB pad controller exposes the following ports:
|
||||
- 4x USB2: usb2-0, usb2-1, usb2-2, usb2-3
|
||||
- 4x super-speed USB: usb3-0, usb3-1, usb3-2, usb3-3
|
||||
|
||||
Examples:
|
||||
=========
|
||||
|
@ -20,6 +20,7 @@ Required properties in pwrap device node.
|
||||
- compatible:
|
||||
"mediatek,mt2701-pwrap" for MT2701/7623 SoCs
|
||||
"mediatek,mt6765-pwrap" for MT6765 SoCs
|
||||
"mediatek,mt6779-pwrap" for MT6779 SoCs
|
||||
"mediatek,mt6797-pwrap" for MT6797 SoCs
|
||||
"mediatek,mt7622-pwrap" for MT7622 SoCs
|
||||
"mediatek,mt8135-pwrap" for MT8135 SoCs
|
||||
|
190
Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
Normal file
190
Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
Normal file
@ -0,0 +1,190 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/usb/nvidia,tegra-xudc.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Device tree binding for NVIDIA Tegra XUSB device mode controller (XUDC)
|
||||
|
||||
description:
|
||||
The Tegra XUDC controller supports both USB 2.0 HighSpeed/FullSpeed and
|
||||
USB 3.0 SuperSpeed protocols.
|
||||
|
||||
maintainers:
|
||||
- Nagarjuna Kristam <nkristam@nvidia.com>
|
||||
- JC Kuo <jckuo@nvidia.com>
|
||||
- Thierry Reding <treding@nvidia.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- nvidia,tegra210-xudc # For Tegra210
|
||||
- nvidia,tegra186-xudc # For Tegra186
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
- description: XUSB device controller registers
|
||||
- description: XUSB device PCI Config registers
|
||||
- description: XUSB device registers.
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
- const: base
|
||||
- const: fpci
|
||||
- const: ipfs
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description: Must contain the XUSB device interrupt.
|
||||
|
||||
clocks:
|
||||
minItems: 4
|
||||
maxItems: 5
|
||||
items:
|
||||
- description: Clock to enable core XUSB dev clock.
|
||||
- description: Clock to enable XUSB super speed clock.
|
||||
- description: Clock to enable XUSB super speed dev clock.
|
||||
- description: Clock to enable XUSB high speed dev clock.
|
||||
- description: Clock to enable XUSB full speed dev clock.
|
||||
|
||||
clock-names:
|
||||
minItems: 4
|
||||
maxItems: 5
|
||||
items:
|
||||
- const: dev
|
||||
- const: ss
|
||||
- const: ss_src
|
||||
- const: fs_src
|
||||
- const: hs_src
|
||||
|
||||
power-domains:
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: XUSBB(device) power-domain
|
||||
- description: XUSBA(superspeed) power-domain
|
||||
|
||||
power-domain-names:
|
||||
maxItems: 2
|
||||
items:
|
||||
- const: dev
|
||||
- const: ss
|
||||
|
||||
nvidia,xusb-padctl:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description:
|
||||
phandle to the XUSB pad controller that is used to configure the USB pads
|
||||
used by the XUDC controller.
|
||||
|
||||
phys:
|
||||
minItems: 1
|
||||
description:
|
||||
Must contain an entry for each entry in phy-names.
|
||||
See ../phy/phy-bindings.txt for details.
|
||||
|
||||
phy-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: usb2-0
|
||||
- const: usb2-1
|
||||
- const: usb2-2
|
||||
- const: usb2-3
|
||||
- const: usb3-0
|
||||
- const: usb3-1
|
||||
- const: usb3-2
|
||||
- const: usb3-3
|
||||
|
||||
avddio-usb-supply:
|
||||
description: PCIe/USB3 analog logic power supply. Must supply 1.05 V.
|
||||
|
||||
hvdd-usb-supply:
|
||||
description: USB controller power supply. Must supply 3.3 V.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- power-domain-names
|
||||
- nvidia,xusb-padctl
|
||||
- phys
|
||||
- phy-names
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra210-xudc
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 3
|
||||
reg-names:
|
||||
minItems: 3
|
||||
clocks:
|
||||
minItems: 5
|
||||
clock-names:
|
||||
minItems: 5
|
||||
required:
|
||||
- avddio-usb-supply
|
||||
- hvdd-usb-supply
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra186-xudc
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 2
|
||||
reg-names:
|
||||
maxItems: 2
|
||||
clocks:
|
||||
maxItems: 4
|
||||
clock-names:
|
||||
maxItems: 4
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra210-car.h>
|
||||
#include <dt-bindings/gpio/tegra-gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
usb@700d0000 {
|
||||
compatible = "nvidia,tegra210-xudc";
|
||||
reg = <0x0 0x700d0000 0x0 0x8000>,
|
||||
<0x0 0x700d8000 0x0 0x1000>,
|
||||
<0x0 0x700d9000 0x0 0x1000>;
|
||||
reg-names = "base", "fpci", "ipfs";
|
||||
|
||||
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_XUSB_DEV>,
|
||||
<&tegra_car TEGRA210_CLK_XUSB_SS>,
|
||||
<&tegra_car TEGRA210_CLK_XUSB_SSP_SRC>,
|
||||
<&tegra_car TEGRA210_CLK_XUSB_FS_SRC>,
|
||||
<&tegra_car TEGRA210_CLK_XUSB_HS_SRC>;
|
||||
clock-names = "dev", "ss", "ss_src", "fs_src", "hs_src";
|
||||
|
||||
power-domains = <&pd_xusbdev>, <&pd_xusbss>;
|
||||
power-domain-names = "dev", "ss";
|
||||
|
||||
nvidia,xusb-padctl = <&padctl>;
|
||||
|
||||
phys = <µ_b>;
|
||||
phy-names = "usb2-0";
|
||||
|
||||
avddio-usb-supply = <&vdd_pex_1v05>;
|
||||
hvdd-usb-supply = <&vdd_3v3_sys>;
|
||||
};
|
@ -1201,23 +1201,49 @@ choice
|
||||
|
||||
config STM32F4_DEBUG_UART
|
||||
bool "Use STM32F4 UART for low-level debug"
|
||||
depends on ARCH_STM32
|
||||
depends on MACH_STM32F429 || MACH_STM32F469
|
||||
select DEBUG_STM32_UART
|
||||
help
|
||||
Say Y here if you want kernel low-level debugging support
|
||||
on STM32F4 based platforms, which default UART is wired on
|
||||
USART1.
|
||||
USART1, but another UART instance can be selected by modifying
|
||||
CONFIG_DEBUG_UART_PHYS.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config STM32F7_DEBUG_UART
|
||||
bool "Use STM32F7 UART for low-level debug"
|
||||
depends on ARCH_STM32
|
||||
depends on MACH_STM32F746 || MACH_STM32F769
|
||||
select DEBUG_STM32_UART
|
||||
help
|
||||
Say Y here if you want kernel low-level debugging support
|
||||
on STM32F7 based platforms, which default UART is wired on
|
||||
USART1.
|
||||
USART1, but another UART instance can be selected by modifying
|
||||
CONFIG_DEBUG_UART_PHYS.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config STM32H7_DEBUG_UART
|
||||
bool "Use STM32H7 UART for low-level debug"
|
||||
depends on MACH_STM32H743
|
||||
select DEBUG_STM32_UART
|
||||
help
|
||||
Say Y here if you want kernel low-level debugging support
|
||||
on STM32H7 based platforms, which default UART is wired on
|
||||
USART1, but another UART instance can be selected by modifying
|
||||
CONFIG_DEBUG_UART_PHYS.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config STM32MP1_DEBUG_UART
|
||||
bool "Use STM32MP1 UART for low-level debug"
|
||||
depends on MACH_STM32MP157
|
||||
select DEBUG_STM32_UART
|
||||
help
|
||||
Say Y here if you want kernel low-level debugging support
|
||||
on STM32MP1 based platforms, wich default UART is wired on
|
||||
UART4, but another UART instance can be selected by modifying
|
||||
CONFIG_DEBUG_UART_PHYS and CONFIG_DEBUG_UART_VIRT.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
@ -1619,6 +1645,9 @@ config DEBUG_UART_PHYS
|
||||
default 0x3e000000 if DEBUG_BCM_KONA_UART
|
||||
default 0x3f201000 if DEBUG_BCM2836
|
||||
default 0x4000e400 if DEBUG_LL_UART_EFM32
|
||||
default 0x40010000 if STM32MP1_DEBUG_UART
|
||||
default 0x40011000 if STM32F4_DEBUG_UART || STM32F7_DEBUG_UART || \
|
||||
STM32H7_DEBUG_UART
|
||||
default 0x40028000 if DEBUG_AT91_SAMV7_USART1
|
||||
default 0x40081000 if DEBUG_LPC18XX_UART0
|
||||
default 0x40090000 if DEBUG_LPC32XX
|
||||
@ -1713,7 +1742,7 @@ config DEBUG_UART_PHYS
|
||||
DEBUG_S3C64XX_UART || \
|
||||
DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
|
||||
DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
|
||||
DEBUG_AT91_UART
|
||||
DEBUG_AT91_UART || DEBUG_STM32_UART
|
||||
|
||||
config DEBUG_UART_VIRT
|
||||
hex "Virtual base address of debug UART"
|
||||
@ -1779,6 +1808,7 @@ config DEBUG_UART_VIRT
|
||||
default 0xfcfe8600 if DEBUG_BCM63XX_UART
|
||||
default 0xfd000000 if DEBUG_SPEAR3XX || DEBUG_SPEAR13XX
|
||||
default 0xfd883000 if DEBUG_ALPINE_UART0
|
||||
default 0xfe010000 if STM32MP1_DEBUG_UART
|
||||
default 0xfe017000 if DEBUG_MMP_UART2
|
||||
default 0xfe018000 if DEBUG_MMP_UART3
|
||||
default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART
|
||||
@ -1823,7 +1853,7 @@ config DEBUG_UART_VIRT
|
||||
DEBUG_S3C64XX_UART || \
|
||||
DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
|
||||
DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
|
||||
DEBUG_AT91_UART
|
||||
DEBUG_AT91_UART || DEBUG_STM32_UART
|
||||
|
||||
config DEBUG_UART_8250_SHIFT
|
||||
int "Register offset shift for the 8250 debug UART"
|
||||
|
@ -152,6 +152,7 @@ textofs-$(CONFIG_PM_H1940) := 0x00108000
|
||||
ifeq ($(CONFIG_ARCH_SA1100),y)
|
||||
textofs-$(CONFIG_SA1111) := 0x00208000
|
||||
endif
|
||||
textofs-$(CONFIG_ARCH_IPQ40XX) := 0x00208000
|
||||
textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
|
||||
textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
|
||||
textofs-$(CONFIG_ARCH_MESON) := 0x00208000
|
||||
|
@ -56,6 +56,8 @@ CONFIG_CPUFREQ_DT=m
|
||||
# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
|
||||
CONFIG_ARM_TI_CPUFREQ=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_ARM_CPUIDLE=y
|
||||
CONFIG_DT_IDLE_STATES=y
|
||||
CONFIG_KERNEL_MODE_NEON=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_ARM_CRYPTO=y
|
||||
|
@ -4,14 +4,13 @@
|
||||
* Author: Gerald Baeza <gerald.baeza@st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#define STM32_UART_BASE 0x40011000 /* USART1 */
|
||||
|
||||
#ifdef CONFIG_STM32F4_DEBUG_UART
|
||||
#define STM32_USART_SR_OFF 0x00
|
||||
#define STM32_USART_TDR_OFF 0x04
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32F7_DEBUG_UART
|
||||
#if defined(CONFIG_STM32F7_DEBUG_UART) || defined(CONFIG_STM32H7_DEBUG_UART) || \
|
||||
defined(CONFIG_STM32MP1_DEBUG_UART)
|
||||
#define STM32_USART_SR_OFF 0x1C
|
||||
#define STM32_USART_TDR_OFF 0x28
|
||||
#endif
|
||||
@ -20,8 +19,8 @@
|
||||
#define STM32_USART_TXE (1 << 7) /* Tx data reg empty */
|
||||
|
||||
.macro addruart, rp, rv, tmp
|
||||
ldr \rp, =STM32_UART_BASE @ physical base
|
||||
ldr \rv, =STM32_UART_BASE @ virt base /* NoMMU */
|
||||
ldr \rp, =CONFIG_DEBUG_UART_PHYS @ physical base
|
||||
ldr \rv, =CONFIG_DEBUG_UART_VIRT @ virt base
|
||||
.endm
|
||||
|
||||
.macro senduart,rd,rx
|
||||
|
@ -153,7 +153,6 @@ config HAVE_AT91_USB_CLK
|
||||
|
||||
config COMMON_CLK_AT91
|
||||
bool
|
||||
select COMMON_CLK
|
||||
select MFD_SYSCON
|
||||
|
||||
config HAVE_AT91_SMD
|
||||
|
@ -736,13 +736,36 @@ static void __init at91_pm_modes_init(void)
|
||||
|
||||
struct pmc_info {
|
||||
unsigned long uhp_udp_mask;
|
||||
unsigned long mckr;
|
||||
unsigned long version;
|
||||
};
|
||||
|
||||
static const struct pmc_info pmc_infos[] __initconst = {
|
||||
{ .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP },
|
||||
{ .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP },
|
||||
{ .uhp_udp_mask = AT91SAM926x_PMC_UHP },
|
||||
{ .uhp_udp_mask = 0 },
|
||||
{
|
||||
.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP,
|
||||
.mckr = 0x30,
|
||||
.version = AT91_PMC_V1,
|
||||
},
|
||||
|
||||
{
|
||||
.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
|
||||
.mckr = 0x30,
|
||||
.version = AT91_PMC_V1,
|
||||
},
|
||||
{
|
||||
.uhp_udp_mask = AT91SAM926x_PMC_UHP,
|
||||
.mckr = 0x30,
|
||||
.version = AT91_PMC_V1,
|
||||
},
|
||||
{ .uhp_udp_mask = 0,
|
||||
.mckr = 0x30,
|
||||
.version = AT91_PMC_V1,
|
||||
},
|
||||
{
|
||||
.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
|
||||
.mckr = 0x28,
|
||||
.version = AT91_PMC_V2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct of_device_id atmel_pmc_ids[] __initconst = {
|
||||
@ -757,7 +780,7 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = {
|
||||
{ .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
|
||||
{ .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
|
||||
{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
|
||||
{ .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[1] },
|
||||
{ .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
@ -779,6 +802,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
|
||||
|
||||
pmc = of_id->data;
|
||||
soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask;
|
||||
soc_pm.data.pmc_mckr_offset = pmc->mckr;
|
||||
soc_pm.data.pmc_version = pmc->version;
|
||||
|
||||
if (pm_idle)
|
||||
arm_pm_idle = pm_idle;
|
||||
|
@ -33,6 +33,8 @@ struct at91_pm_data {
|
||||
void __iomem *sfrbu;
|
||||
unsigned int standby_mode;
|
||||
unsigned int suspend_mode;
|
||||
unsigned int pmc_mckr_offset;
|
||||
unsigned int pmc_version;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -12,6 +12,10 @@ int main(void)
|
||||
DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode));
|
||||
DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc));
|
||||
DEFINE(PM_DATA_SFRBU, offsetof(struct at91_pm_data, sfrbu));
|
||||
DEFINE(PM_DATA_PMC_MCKR_OFFSET, offsetof(struct at91_pm_data,
|
||||
pmc_mckr_offset));
|
||||
DEFINE(PM_DATA_PMC_VERSION, offsetof(struct at91_pm_data,
|
||||
pmc_version));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
pmc .req r0
|
||||
tmp1 .req r4
|
||||
tmp2 .req r5
|
||||
tmp3 .req r6
|
||||
|
||||
/*
|
||||
* Wait until master clock is ready (after switching master clock source)
|
||||
@ -93,13 +94,17 @@ ENTRY(at91_pm_suspend_in_sram)
|
||||
str tmp1, .memtype
|
||||
ldr tmp1, [r0, #PM_DATA_MODE]
|
||||
str tmp1, .pm_mode
|
||||
ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
|
||||
str tmp1, .mckr_offset
|
||||
ldr tmp1, [r0, #PM_DATA_PMC_VERSION]
|
||||
str tmp1, .pmc_version
|
||||
/* Both ldrne below are here to preload their address in the TLB */
|
||||
ldr tmp1, [r0, #PM_DATA_SHDWC]
|
||||
str tmp1, .shdwc
|
||||
cmp tmp1, #0
|
||||
ldrne tmp2, [tmp1, #0]
|
||||
ldr tmp1, [r0, #PM_DATA_SFRBU]
|
||||
str tmp1, .sfr
|
||||
str tmp1, .sfrbu
|
||||
cmp tmp1, #0
|
||||
ldrne tmp2, [tmp1, #0x10]
|
||||
|
||||
@ -138,14 +143,15 @@ ENDPROC(at91_pm_suspend_in_sram)
|
||||
ENTRY(at91_backup_mode)
|
||||
/* Switch the master clock source to slow clock. */
|
||||
ldr pmc, .pmc_base
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp2, .mckr_offset
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
/*BUMEN*/
|
||||
ldr r0, .sfr
|
||||
ldr r0, .sfrbu
|
||||
mov tmp1, #0x1
|
||||
str tmp1, [r0, #0x10]
|
||||
|
||||
@ -218,6 +224,7 @@ ENDPROC(at91_backup_mode)
|
||||
*/
|
||||
.macro at91_pm_ulp1_mode
|
||||
ldr pmc, .pmc_base
|
||||
ldr tmp2, .mckr_offset
|
||||
|
||||
/* Save RC oscillator state and check if it is enabled. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
@ -254,10 +261,10 @@ ENDPROC(at91_backup_mode)
|
||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
|
||||
/* Switch the master clock source to main clock */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
@ -268,6 +275,10 @@ ENDPROC(at91_backup_mode)
|
||||
orr tmp1, tmp1, #AT91_PMC_KEY
|
||||
str tmp1, [pmc, #AT91_CKGR_MOR]
|
||||
|
||||
/* Quirk for SAM9X60's PMC */
|
||||
nop
|
||||
nop
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
/* Enable the crystal oscillator */
|
||||
@ -280,9 +291,9 @@ ENDPROC(at91_backup_mode)
|
||||
wait_moscrdy
|
||||
|
||||
/* Switch the master clock source to slow clock */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
@ -296,10 +307,10 @@ ENDPROC(at91_backup_mode)
|
||||
wait_moscsels
|
||||
|
||||
/* Switch the master clock source to main clock */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
@ -323,21 +334,160 @@ ENDPROC(at91_backup_mode)
|
||||
3:
|
||||
.endm
|
||||
|
||||
.macro at91_plla_disable
|
||||
/* Save PLLA setting and disable it */
|
||||
ldr tmp1, .pmc_version
|
||||
cmp tmp1, #AT91_PMC_V1
|
||||
beq 1f
|
||||
|
||||
#ifdef CONFIG_SOC_SAM9X60
|
||||
/* Save PLLA settings. */
|
||||
ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp2, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* save div. */
|
||||
mov tmp1, #0
|
||||
ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
bic tmp2, tmp2, #0xffffff00
|
||||
orr tmp1, tmp1, tmp2
|
||||
|
||||
/* save mul. */
|
||||
ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1]
|
||||
bic tmp2, tmp2, #0xffffff
|
||||
orr tmp1, tmp1, tmp2
|
||||
str tmp1, .saved_pllar
|
||||
|
||||
/* step 2. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 3. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
|
||||
/* step 4. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 5. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
|
||||
/* step 7. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
b 2f
|
||||
#endif
|
||||
|
||||
1: /* Save PLLA setting and disable it */
|
||||
ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
str tmp1, .saved_pllar
|
||||
|
||||
/* Disable PLLA. */
|
||||
mov tmp1, #AT91_PMC_PLLCOUNT
|
||||
orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
|
||||
str tmp1, [pmc, #AT91_CKGR_PLLAR]
|
||||
2:
|
||||
.endm
|
||||
|
||||
.macro at91_plla_enable
|
||||
ldr tmp2, .saved_pllar
|
||||
ldr tmp3, .pmc_version
|
||||
cmp tmp3, #AT91_PMC_V1
|
||||
beq 4f
|
||||
|
||||
#ifdef CONFIG_SOC_SAM9X60
|
||||
/* step 1. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 2. */
|
||||
ldr tmp1, =#AT91_PMC_PLL_ACR_DEFAULT_PLLA
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_ACR]
|
||||
|
||||
/* step 3. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
|
||||
mov tmp3, tmp2
|
||||
bic tmp3, tmp3, #0xffffff
|
||||
orr tmp1, tmp1, tmp3
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
|
||||
|
||||
/* step 8. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 9. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
|
||||
bic tmp1, tmp1, #0xff
|
||||
mov tmp3, tmp2
|
||||
bic tmp3, tmp3, #0xffffff00
|
||||
orr tmp1, tmp1, tmp3
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
|
||||
|
||||
/* step 10. */
|
||||
ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
|
||||
bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
|
||||
str tmp1, [pmc, #AT91_PMC_PLL_UPDT]
|
||||
|
||||
/* step 11. */
|
||||
3: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0]
|
||||
tst tmp1, #0x1
|
||||
beq 3b
|
||||
b 2f
|
||||
#endif
|
||||
|
||||
/* Restore PLLA setting */
|
||||
4: str tmp2, [pmc, #AT91_CKGR_PLLAR]
|
||||
|
||||
/* Enable PLLA. */
|
||||
tst tmp2, #(AT91_PMC_MUL & 0xff0000)
|
||||
bne 1f
|
||||
tst tmp2, #(AT91_PMC_MUL & ~0xff0000)
|
||||
beq 2f
|
||||
|
||||
1: ldr tmp1, [pmc, #AT91_PMC_SR]
|
||||
tst tmp1, #AT91_PMC_LOCKA
|
||||
beq 1b
|
||||
2:
|
||||
.endm
|
||||
|
||||
ENTRY(at91_ulp_mode)
|
||||
ldr pmc, .pmc_base
|
||||
ldr tmp2, .mckr_offset
|
||||
|
||||
/* Save Master clock setting */
|
||||
ldr tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, [pmc, tmp2]
|
||||
str tmp1, .saved_mckr
|
||||
|
||||
/*
|
||||
* Set the Master clock source to slow clock
|
||||
*/
|
||||
bic tmp1, tmp1, #AT91_PMC_CSS
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
str tmp1, [pmc, tmp2]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
at91_plla_disable
|
||||
|
||||
ldr r0, .pm_mode
|
||||
cmp r0, #AT91_PM_ULP1
|
||||
beq ulp1_mode
|
||||
@ -352,11 +502,14 @@ ulp1_mode:
|
||||
ulp_exit:
|
||||
ldr pmc, .pmc_base
|
||||
|
||||
at91_plla_enable
|
||||
|
||||
/*
|
||||
* Restore master clock setting
|
||||
*/
|
||||
ldr tmp1, .saved_mckr
|
||||
str tmp1, [pmc, #AT91_PMC_MCKR]
|
||||
ldr tmp1, .mckr_offset
|
||||
ldr tmp2, .saved_mckr
|
||||
str tmp2, [pmc, tmp1]
|
||||
|
||||
wait_mckrdy
|
||||
|
||||
@ -496,14 +649,20 @@ ENDPROC(at91_sramc_self_refresh)
|
||||
.word 0
|
||||
.shdwc:
|
||||
.word 0
|
||||
.sfr:
|
||||
.sfrbu:
|
||||
.word 0
|
||||
.memtype:
|
||||
.word 0
|
||||
.pm_mode:
|
||||
.word 0
|
||||
.mckr_offset:
|
||||
.word 0
|
||||
.pmc_version:
|
||||
.word 0
|
||||
.saved_mckr:
|
||||
.word 0
|
||||
.saved_pllar:
|
||||
.word 0
|
||||
.saved_sam9_lpr:
|
||||
.word 0
|
||||
.saved_sam9_lpr1:
|
||||
|
@ -20,7 +20,6 @@ config ARCH_BCM_IPROC
|
||||
select GPIOLIB
|
||||
select ARM_AMBA
|
||||
select PINCTRL
|
||||
select PCI_DOMAINS_GENERIC if PCI
|
||||
help
|
||||
This enables support for systems based on Broadcom IPROC architected SoCs.
|
||||
The IPROC complex contains one or more ARM CPUs along with common
|
||||
@ -54,7 +53,6 @@ config ARCH_BCM_NSP
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_775420
|
||||
select ARM_ERRATA_764369 if SMP
|
||||
select HAVE_SMP
|
||||
select THERMAL
|
||||
select THERMAL_OF
|
||||
help
|
||||
@ -73,7 +71,6 @@ config ARCH_BCM_5301X
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_775420
|
||||
select ARM_ERRATA_764369 if SMP
|
||||
select HAVE_SMP
|
||||
|
||||
help
|
||||
Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
|
||||
@ -109,7 +106,6 @@ config ARCH_BCM_281XX
|
||||
bool "Broadcom BCM281XX SoC family"
|
||||
depends on ARCH_MULTI_V7
|
||||
select ARCH_BCM_MOBILE
|
||||
select HAVE_SMP
|
||||
help
|
||||
Enable support for the BCM281XX family, which includes
|
||||
BCM11130, BCM11140, BCM11351, BCM28145 and BCM28155
|
||||
@ -119,7 +115,6 @@ config ARCH_BCM_21664
|
||||
bool "Broadcom BCM21664 SoC family"
|
||||
depends on ARCH_MULTI_V7
|
||||
select ARCH_BCM_MOBILE
|
||||
select HAVE_SMP
|
||||
help
|
||||
Enable support for the BCM21664 family, which includes
|
||||
BCM21663 and BCM21664 variants.
|
||||
@ -128,7 +123,6 @@ config ARCH_BCM_23550
|
||||
bool "Broadcom BCM23550 SoC"
|
||||
depends on ARCH_MULTI_V7
|
||||
select ARCH_BCM_MOBILE
|
||||
select HAVE_SMP
|
||||
help
|
||||
Enable support for the BCM23550.
|
||||
|
||||
@ -165,7 +159,6 @@ config ARCH_BCM2835
|
||||
select ZONE_DMA if ARCH_MULTI_V7
|
||||
select ARM_TIMER_SP804
|
||||
select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
|
||||
select TIMER_OF
|
||||
select BCM2835_TIMER
|
||||
select PINCTRL
|
||||
select PINCTRL_BCM2835
|
||||
@ -201,7 +194,6 @@ config ARCH_BCM_63XX
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select HAVE_ARM_TWD if SMP
|
||||
select HAVE_ARM_SCU if SMP
|
||||
select HAVE_SMP
|
||||
help
|
||||
This enables support for systems based on Broadcom DSL SoCs.
|
||||
It currently supports the 'BCM63XX' ARM-based family, which includes
|
||||
|
@ -189,12 +189,6 @@ static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction cns3xxx_timer_irq = {
|
||||
.name = "timer",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = cns3xxx_timer_interrupt,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up the clock source and clock events devices
|
||||
*/
|
||||
@ -245,7 +239,9 @@ static void __init __cns3xxx_timer_init(unsigned int timer_irq)
|
||||
writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
|
||||
|
||||
/* Make irqs happen for the system timer */
|
||||
setup_irq(timer_irq, &cns3xxx_timer_irq);
|
||||
if (request_irq(timer_irq, cns3xxx_timer_interrupt,
|
||||
IRQF_TIMER | IRQF_IRQPOLL, "timer", NULL))
|
||||
pr_err("Failed to request irq %d (timer)\n", timer_irq);
|
||||
|
||||
cns3xxx_clockevents_init(timer_irq);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@
|
||||
/*****************************************************************************
|
||||
* I/O Address Mapping
|
||||
****************************************************************************/
|
||||
static struct map_desc dove_io_desc[] __initdata = {
|
||||
static struct map_desc __maybe_unused dove_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = (unsigned long) DOVE_SB_REGS_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE),
|
||||
|
@ -117,15 +117,11 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction ep93xx_timer_irq = {
|
||||
.name = "ep93xx timer",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = ep93xx_timer_interrupt,
|
||||
.dev_id = &ep93xx_clockevent,
|
||||
};
|
||||
|
||||
void __init ep93xx_timer_init(void)
|
||||
{
|
||||
int irq = IRQ_EP93XX_TIMER3;
|
||||
unsigned long flags = IRQF_TIMER | IRQF_IRQPOLL;
|
||||
|
||||
/* Enable and register clocksource and sched_clock on timer 4 */
|
||||
writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
|
||||
EP93XX_TIMER4_VALUE_HIGH);
|
||||
@ -136,7 +132,9 @@ void __init ep93xx_timer_init(void)
|
||||
EP93XX_TIMER4_RATE);
|
||||
|
||||
/* Set up clockevent on timer 3 */
|
||||
setup_irq(IRQ_EP93XX_TIMER3, &ep93xx_timer_irq);
|
||||
if (request_irq(irq, ep93xx_timer_interrupt, flags, "ep93xx timer",
|
||||
&ep93xx_clockevent))
|
||||
pr_err("Failed to request irq %d (ep93xx timer)\n", irq);
|
||||
clockevents_config_and_register(&ep93xx_clockevent,
|
||||
EP93XX_TIMER123_RATE,
|
||||
1,
|
||||
|
@ -471,8 +471,6 @@ config SOC_IMX53
|
||||
config SOC_IMX6
|
||||
bool
|
||||
select ARM_CPU_SUSPEND if (PM || CPU_IDLE)
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_775420
|
||||
select ARM_GIC
|
||||
select HAVE_IMX_ANATOP
|
||||
select HAVE_IMX_GPC
|
||||
@ -484,6 +482,8 @@ config SOC_IMX6
|
||||
config SOC_IMX6Q
|
||||
bool "i.MX6 Quad/DualLite support"
|
||||
select ARM_ERRATA_764369 if SMP
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_775420
|
||||
select HAVE_ARM_SCU if SMP
|
||||
select HAVE_ARM_TWD
|
||||
select PINCTRL_IMX6Q
|
||||
@ -494,6 +494,8 @@ config SOC_IMX6Q
|
||||
|
||||
config SOC_IMX6SL
|
||||
bool "i.MX6 SoloLite support"
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_775420
|
||||
select PINCTRL_IMX6SL
|
||||
select SOC_IMX6
|
||||
|
||||
@ -502,6 +504,8 @@ config SOC_IMX6SL
|
||||
|
||||
config SOC_IMX6SLL
|
||||
bool "i.MX6 SoloLiteLite support"
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_775420
|
||||
select PINCTRL_IMX6SLL
|
||||
select SOC_IMX6
|
||||
|
||||
@ -510,6 +514,8 @@ config SOC_IMX6SLL
|
||||
|
||||
config SOC_IMX6SX
|
||||
bool "i.MX6 SoloX support"
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_775420
|
||||
select PINCTRL_IMX6SX
|
||||
select SOC_IMX6
|
||||
|
||||
|
@ -89,12 +89,11 @@ void imx_anatop_post_resume(void)
|
||||
|
||||
if (cpu_is_imx6sl())
|
||||
imx_anatop_disconnect_high_snvs(false);
|
||||
|
||||
}
|
||||
|
||||
void __init imx_init_revision_from_anatop(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct device_node *np, *src_np;
|
||||
void __iomem *anatop_base;
|
||||
unsigned int revision;
|
||||
u32 digprog;
|
||||
@ -135,9 +134,10 @@ void __init imx_init_revision_from_anatop(void)
|
||||
void __iomem *src_base;
|
||||
u32 sbmr2;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL,
|
||||
src_np = of_find_compatible_node(NULL, NULL,
|
||||
"fsl,imx6ul-src");
|
||||
src_base = of_iomap(np, 0);
|
||||
of_node_put(src_np);
|
||||
WARN_ON(!src_base);
|
||||
sbmr2 = readl_relaxed(src_base + SRC_SBMR2);
|
||||
iounmap(src_base);
|
||||
@ -149,6 +149,7 @@ void __init imx_init_revision_from_anatop(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
of_node_put(np);
|
||||
|
||||
mxc_set_cpu_type(digprog >> 16 & 0xff);
|
||||
imx_set_soc_revision(revision);
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/irqchip/arm-gic.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
|
||||
@ -111,7 +111,6 @@ void imx_gpc_mask_all(void)
|
||||
gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
|
||||
writel_relaxed(~0, reg_imr1 + i * 4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void imx_gpc_restore_all(void)
|
||||
@ -282,4 +281,5 @@ void __init imx_gpc_check_dt(void)
|
||||
/* map GPC, so that at least CPUidle and WARs keep working */
|
||||
gpc_base = of_iomap(np, 0);
|
||||
}
|
||||
of_node_put(np);
|
||||
}
|
||||
|
@ -5,29 +5,16 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/micrel_phy.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/system_misc.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "cpuidle.h"
|
||||
|
@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
|
||||
|
@ -25,7 +25,6 @@ static void __init imx6ul_enet_clk_init(void)
|
||||
IMX6UL_GPR1_ENET_CLK_OUTPUT);
|
||||
else
|
||||
pr_err("failed to find fsl,imx6ul-iomux-gpr regmap\n");
|
||||
|
||||
}
|
||||
|
||||
static int ksz8081_phy_fixup(struct phy_device *dev)
|
||||
|
@ -109,6 +109,7 @@ static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus)
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg");
|
||||
dcfg_base = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
BUG_ON(!dcfg_base);
|
||||
|
||||
paddr = __pa_symbol(secondary_startup);
|
||||
|
@ -655,6 +655,8 @@ void __init imx6_pm_ccm_init(const char *ccm_compat)
|
||||
|
||||
if (of_property_read_bool(np, "fsl,pmic-stby-poweroff"))
|
||||
imx6_pm_stby_poweroff_probe();
|
||||
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
void __init imx6q_pm_init(void)
|
||||
|
@ -62,6 +62,7 @@ void __init imx7ulp_pm_init(void)
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1");
|
||||
smc1_base = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
WARN_ON(!smc1_base);
|
||||
|
||||
imx7ulp_set_lpm(ULP_PM_RUN);
|
||||
|
@ -43,9 +43,6 @@ static int imx_src_reset_module(struct reset_controller_dev *rcdev,
|
||||
int bit;
|
||||
u32 val;
|
||||
|
||||
if (!src_base)
|
||||
return -ENODEV;
|
||||
|
||||
if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -137,13 +137,6 @@ iop_timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction iop_timer_irq = {
|
||||
.name = "IOP Timer Tick",
|
||||
.handler = iop_timer_interrupt,
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.dev_id = &iop_clockevent,
|
||||
};
|
||||
|
||||
static unsigned long iop_tick_rate;
|
||||
unsigned long get_iop_tick_rate(void)
|
||||
{
|
||||
@ -154,6 +147,7 @@ EXPORT_SYMBOL(get_iop_tick_rate);
|
||||
void __init iop_init_time(unsigned long tick_rate)
|
||||
{
|
||||
u32 timer_ctl;
|
||||
int irq = IRQ_IOP32X_TIMER0;
|
||||
|
||||
sched_clock_register(iop_read_sched_clock, 32, tick_rate);
|
||||
|
||||
@ -168,7 +162,9 @@ void __init iop_init_time(unsigned long tick_rate)
|
||||
*/
|
||||
write_tmr0(timer_ctl & ~IOP_TMR_EN);
|
||||
write_tisr(1);
|
||||
setup_irq(IRQ_IOP32X_TIMER0, &iop_timer_irq);
|
||||
if (request_irq(irq, iop_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
|
||||
"IOP Timer Tick", &iop_clockevent))
|
||||
pr_err("Failed to request irq() %d (IOP Timer Tick)\n", irq);
|
||||
iop_clockevent.cpumask = cpumask_of(0);
|
||||
clockevents_config_and_register(&iop_clockevent, tick_rate,
|
||||
0xf, 0xfffffffe);
|
||||
|
@ -175,13 +175,6 @@ static void __init timer_config(void)
|
||||
__raw_writel(0x2, mmp_timer_base + TMR_CER);
|
||||
}
|
||||
|
||||
static struct irqaction timer_irq = {
|
||||
.name = "timer",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = timer_interrupt,
|
||||
.dev_id = &ckevt,
|
||||
};
|
||||
|
||||
void __init mmp_timer_init(int irq, unsigned long rate)
|
||||
{
|
||||
timer_config();
|
||||
@ -190,7 +183,9 @@ void __init mmp_timer_init(int irq, unsigned long rate)
|
||||
|
||||
ckevt.cpumask = cpumask_of(0);
|
||||
|
||||
setup_irq(irq, &timer_irq);
|
||||
if (request_irq(irq, timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
|
||||
"timer", &ckevt))
|
||||
pr_err("Failed to request irq %d (timer)\n", irq);
|
||||
|
||||
clocksource_register_hz(&cksrc, rate);
|
||||
clockevents_config_and_register(&ckevt, rate, MIN_DELTA, MAX_DELTA);
|
||||
|
@ -596,11 +596,6 @@ static irqreturn_t omap_wakeup_interrupt(int irq, void *dev)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction omap_wakeup_irq = {
|
||||
.name = "peripheral wakeup",
|
||||
.handler = omap_wakeup_interrupt
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const struct platform_suspend_ops omap_pm_ops = {
|
||||
@ -613,6 +608,7 @@ static const struct platform_suspend_ops omap_pm_ops = {
|
||||
static int __init omap_pm_init(void)
|
||||
{
|
||||
int error = 0;
|
||||
int irq;
|
||||
|
||||
if (!cpu_class_is_omap1())
|
||||
return -ENODEV;
|
||||
@ -656,9 +652,12 @@ static int __init omap_pm_init(void)
|
||||
arm_pm_idle = omap1_pm_idle;
|
||||
|
||||
if (cpu_is_omap7xx())
|
||||
setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
irq = INT_7XX_WAKE_UP_REQ;
|
||||
else if (cpu_is_omap16xx())
|
||||
setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
irq = INT_1610_WAKE_UP_REQ;
|
||||
if (request_irq(irq, omap_wakeup_interrupt, 0, "peripheral wakeup",
|
||||
NULL))
|
||||
pr_err("Failed to request irq %d (peripheral wakeup)\n", irq);
|
||||
|
||||
/* Program new power ramp-up time
|
||||
* (0 for most boards since we don't lower voltage when in deep sleep)
|
||||
|
@ -155,15 +155,11 @@ static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction omap_mpu_timer1_irq = {
|
||||
.name = "mpu_timer1",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = omap_mpu_timer1_interrupt,
|
||||
};
|
||||
|
||||
static __init void omap_init_mpu_timer(unsigned long rate)
|
||||
{
|
||||
setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
|
||||
if (request_irq(INT_TIMER1, omap_mpu_timer1_interrupt,
|
||||
IRQF_TIMER | IRQF_IRQPOLL, "mpu_timer1", NULL))
|
||||
pr_err("Failed to request irq %d (mpu_timer1)\n", INT_TIMER1);
|
||||
omap_mpu_timer_start(0, (rate / HZ) - 1, 1);
|
||||
|
||||
clockevent_mpu_timer1.cpumask = cpumask_of(0);
|
||||
|
@ -148,15 +148,11 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction omap_32k_timer_irq = {
|
||||
.name = "32KHz timer",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = omap_32k_timer_interrupt,
|
||||
};
|
||||
|
||||
static __init void omap_init_32k_timer(void)
|
||||
{
|
||||
setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
|
||||
if (request_irq(INT_OS_TIMER, omap_32k_timer_interrupt,
|
||||
IRQF_TIMER | IRQF_IRQPOLL, "32KHz timer", NULL))
|
||||
pr_err("Failed to request irq %d(32KHz timer)\n", INT_OS_TIMER);
|
||||
|
||||
clockevent_32k_timer.cpumask = cpumask_of(0);
|
||||
clockevents_config_and_register(&clockevent_32k_timer,
|
||||
|
@ -3148,15 +3148,14 @@ static int omap_hwmod_check_sysc(struct device *dev,
|
||||
/**
|
||||
* omap_hwmod_init_regbits - init sysconfig specific register bits
|
||||
* @dev: struct device
|
||||
* @oh: module
|
||||
* @data: module data
|
||||
* @sysc_fields: new sysc configuration
|
||||
*/
|
||||
static int omap_hwmod_init_regbits(struct device *dev,
|
||||
static int omap_hwmod_init_regbits(struct device *dev, struct omap_hwmod *oh,
|
||||
const struct ti_sysc_module_data *data,
|
||||
struct sysc_regbits **sysc_fields)
|
||||
{
|
||||
*sysc_fields = NULL;
|
||||
|
||||
switch (data->cap->type) {
|
||||
case TI_SYSC_OMAP2:
|
||||
case TI_SYSC_OMAP2_TIMER:
|
||||
@ -3191,6 +3190,12 @@ static int omap_hwmod_init_regbits(struct device *dev,
|
||||
*sysc_fields = &omap_hwmod_sysc_type_usb_host_fs;
|
||||
break;
|
||||
default:
|
||||
*sysc_fields = NULL;
|
||||
if (!oh->class->sysc->sysc_fields)
|
||||
return 0;
|
||||
|
||||
dev_err(dev, "sysc_fields not found\n");
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -3356,9 +3361,9 @@ static int omap_hwmod_check_module(struct device *dev,
|
||||
if (!oh->class->sysc)
|
||||
return -ENODEV;
|
||||
|
||||
if (sysc_fields != oh->class->sysc->sysc_fields)
|
||||
dev_warn(dev, "sysc_fields %p != %p\n", sysc_fields,
|
||||
oh->class->sysc->sysc_fields);
|
||||
if (oh->class->sysc->sysc_fields &&
|
||||
sysc_fields != oh->class->sysc->sysc_fields)
|
||||
dev_warn(dev, "sysc_fields mismatch\n");
|
||||
|
||||
if (rev_offs != oh->class->sysc->rev_offs)
|
||||
dev_warn(dev, "rev_offs %08x != %08x\n", rev_offs,
|
||||
@ -3574,7 +3579,7 @@ int omap_hwmod_init_module(struct device *dev,
|
||||
|
||||
cookie->data = oh;
|
||||
|
||||
error = omap_hwmod_init_regbits(dev, data, &sysc_fields);
|
||||
error = omap_hwmod_init_regbits(dev, oh, data, &sysc_fields);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -6,11 +6,14 @@
|
||||
* Dave Gerlach
|
||||
*/
|
||||
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/platform_data/pm33xx.h>
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/smp_scu.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_data/pm33xx.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/platform_data/gpio-omap.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/wkup_m3_ipc.h>
|
||||
@ -35,6 +38,14 @@ static struct clockdomain *gfx_l4ls_clkdm;
|
||||
static void __iomem *scu_base;
|
||||
static struct omap_hwmod *rtc_oh;
|
||||
|
||||
static int (*idle_fn)(u32 wfi_flags);
|
||||
|
||||
struct amx3_idle_state {
|
||||
int wfi_flags;
|
||||
};
|
||||
|
||||
static struct amx3_idle_state *idle_states;
|
||||
|
||||
static int am43xx_map_scu(void)
|
||||
{
|
||||
scu_base = ioremap(scu_a9_get_base(), SZ_256);
|
||||
@ -68,7 +79,7 @@ static int am43xx_check_off_mode_enable(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amx3_common_init(void)
|
||||
static int amx3_common_init(int (*idle)(u32 wfi_flags))
|
||||
{
|
||||
gfx_pwrdm = pwrdm_lookup("gfx_pwrdm");
|
||||
per_pwrdm = pwrdm_lookup("per_pwrdm");
|
||||
@ -88,10 +99,12 @@ static int amx3_common_init(void)
|
||||
else
|
||||
omap_set_pwrdm_state(cefuse_pwrdm, PWRDM_POWER_OFF);
|
||||
|
||||
idle_fn = idle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int am33xx_suspend_init(void)
|
||||
static int am33xx_suspend_init(int (*idle)(u32 wfi_flags))
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -102,12 +115,12 @@ static int am33xx_suspend_init(void)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = amx3_common_init();
|
||||
ret = amx3_common_init(idle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int am43xx_suspend_init(void)
|
||||
static int am43xx_suspend_init(int (*idle)(u32 wfi_flags))
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@ -117,11 +130,17 @@ static int am43xx_suspend_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = amx3_common_init();
|
||||
ret = amx3_common_init(idle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amx3_suspend_deinit(void)
|
||||
{
|
||||
idle_fn = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amx3_pre_suspend_common(void)
|
||||
{
|
||||
omap_set_pwrdm_state(gfx_pwrdm, PWRDM_POWER_OFF);
|
||||
@ -201,6 +220,43 @@ static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int am33xx_cpu_suspend(int (*fn)(unsigned long), unsigned long args)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (omap_irq_pending() || need_resched())
|
||||
return ret;
|
||||
|
||||
ret = cpu_suspend(args, fn);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int am43xx_cpu_suspend(int (*fn)(unsigned long), unsigned long args)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!scu_base)
|
||||
return 0;
|
||||
|
||||
scu_power_mode(scu_base, SCU_PM_DORMANT);
|
||||
ret = cpu_suspend(args, fn);
|
||||
scu_power_mode(scu_base, SCU_PM_NORMAL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void amx3_begin_suspend(void)
|
||||
{
|
||||
cpu_idle_poll_ctrl(true);
|
||||
}
|
||||
|
||||
static void amx3_finish_suspend(void)
|
||||
{
|
||||
cpu_idle_poll_ctrl(false);
|
||||
}
|
||||
|
||||
|
||||
static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void)
|
||||
{
|
||||
if (soc_is_am33xx())
|
||||
@ -253,7 +309,11 @@ static void am43xx_prepare_rtc_resume(void)
|
||||
|
||||
static struct am33xx_pm_platform_data am33xx_ops = {
|
||||
.init = am33xx_suspend_init,
|
||||
.deinit = amx3_suspend_deinit,
|
||||
.soc_suspend = am33xx_suspend,
|
||||
.cpu_suspend = am33xx_cpu_suspend,
|
||||
.begin_suspend = amx3_begin_suspend,
|
||||
.finish_suspend = amx3_finish_suspend,
|
||||
.get_sram_addrs = amx3_get_sram_addrs,
|
||||
.save_context = am33xx_save_context,
|
||||
.restore_context = am33xx_restore_context,
|
||||
@ -265,7 +325,11 @@ static struct am33xx_pm_platform_data am33xx_ops = {
|
||||
|
||||
static struct am33xx_pm_platform_data am43xx_ops = {
|
||||
.init = am43xx_suspend_init,
|
||||
.deinit = amx3_suspend_deinit,
|
||||
.soc_suspend = am43xx_suspend,
|
||||
.cpu_suspend = am43xx_cpu_suspend,
|
||||
.begin_suspend = amx3_begin_suspend,
|
||||
.finish_suspend = amx3_finish_suspend,
|
||||
.get_sram_addrs = amx3_get_sram_addrs,
|
||||
.save_context = am43xx_save_context,
|
||||
.restore_context = am43xx_restore_context,
|
||||
@ -301,3 +365,64 @@ int __init amx3_common_pm_init(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init amx3_idle_init(struct device_node *cpu_node, int cpu)
|
||||
{
|
||||
struct device_node *state_node;
|
||||
struct amx3_idle_state states[CPUIDLE_STATE_MAX];
|
||||
int i;
|
||||
int state_count = 1;
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
|
||||
if (!state_node)
|
||||
break;
|
||||
|
||||
if (!of_device_is_available(state_node))
|
||||
continue;
|
||||
|
||||
if (i == CPUIDLE_STATE_MAX) {
|
||||
pr_warn("%s: cpuidle states reached max possible\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
|
||||
states[state_count].wfi_flags = 0;
|
||||
|
||||
if (of_property_read_bool(state_node, "ti,idle-wkup-m3"))
|
||||
states[state_count].wfi_flags |= WFI_FLAG_WAKE_M3 |
|
||||
WFI_FLAG_FLUSH_CACHE;
|
||||
|
||||
state_count++;
|
||||
}
|
||||
|
||||
idle_states = kcalloc(state_count, sizeof(*idle_states), GFP_KERNEL);
|
||||
if (!idle_states)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 1; i < state_count; i++)
|
||||
idle_states[i].wfi_flags = states[i].wfi_flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amx3_idle_enter(unsigned long index)
|
||||
{
|
||||
struct amx3_idle_state *idle_state = &idle_states[index];
|
||||
|
||||
if (!idle_state)
|
||||
return -EINVAL;
|
||||
|
||||
if (idle_fn)
|
||||
idle_fn(idle_state->wfi_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpuidle_ops amx3_cpuidle_ops __initdata = {
|
||||
.init = amx3_idle_init,
|
||||
.suspend = amx3_idle_enter,
|
||||
};
|
||||
|
||||
CPUIDLE_METHOD_OF_DECLARE(pm33xx_idle, "ti,am3352", &amx3_cpuidle_ops);
|
||||
CPUIDLE_METHOD_OF_DECLARE(pm43xx_idle, "ti,am4372", &amx3_cpuidle_ops);
|
||||
|
@ -91,12 +91,6 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction omap2_gp_timer_irq = {
|
||||
.name = "gp_timer",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = omap2_gp_timer_interrupt,
|
||||
};
|
||||
|
||||
static int omap2_gp_timer_set_next_event(unsigned long cycles,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
@ -382,8 +376,9 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
|
||||
&clockevent_gpt.name, OMAP_TIMER_POSTED);
|
||||
BUG_ON(res);
|
||||
|
||||
omap2_gp_timer_irq.dev_id = &clkev;
|
||||
setup_irq(clkev.irq, &omap2_gp_timer_irq);
|
||||
if (request_irq(clkev.irq, omap2_gp_timer_interrupt,
|
||||
IRQF_TIMER | IRQF_IRQPOLL, "gp_timer", &clkev))
|
||||
pr_err("Failed to request irq %d (gp_timer)\n", clkev.irq);
|
||||
|
||||
__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
|
||||
|
||||
|
@ -3,7 +3,6 @@ menuconfig ARCH_ORION5X
|
||||
bool "Marvell Orion"
|
||||
depends on MMU && ARCH_MULTI_V5
|
||||
select CPU_FEROCEON
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GPIOLIB
|
||||
select MVEBU_MBUS
|
||||
select FORCE_PCI
|
||||
@ -18,7 +17,6 @@ if ARCH_ORION5X
|
||||
|
||||
config ARCH_ORION5X_DT
|
||||
bool "Marvell Orion5x Flattened Device Tree"
|
||||
select USE_OF
|
||||
select ORION_CLK
|
||||
select ORION_IRQCHIP
|
||||
select ORION_TIMER
|
||||
|
@ -398,7 +398,6 @@ static int ts78xx_fpga_load_devices(void)
|
||||
|
||||
static int ts78xx_fpga_unload_devices(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ts78xx_fpga.supports.ts_rtc.present == 1)
|
||||
ts78xx_ts_rtc_unload();
|
||||
@ -407,7 +406,7 @@ static int ts78xx_fpga_unload_devices(void)
|
||||
if (ts78xx_fpga.supports.ts_rng.present == 1)
|
||||
ts78xx_ts_rng_unload();
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ts78xx_fpga_load(void)
|
||||
|
@ -12,6 +12,11 @@ menuconfig ARCH_QCOM
|
||||
|
||||
if ARCH_QCOM
|
||||
|
||||
config ARCH_IPQ40XX
|
||||
bool "Enable support for IPQ40XX"
|
||||
select CLKSRC_QCOM
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
|
||||
config ARCH_MSM8X60
|
||||
bool "Enable support for MSM8X60"
|
||||
select CLKSRC_QCOM
|
||||
|
@ -72,7 +72,6 @@ static const char *const r8a7779_compat_dt[] __initconst = {
|
||||
DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)")
|
||||
.smp = smp_ops(r8a7779_smp_ops),
|
||||
.map_io = r8a7779_map_io,
|
||||
.init_early = shmobile_init_delay,
|
||||
.init_irq = r8a7779_init_irq_dt,
|
||||
.init_late = shmobile_init_late,
|
||||
.dt_compat = r8a7779_compat_dt,
|
||||
|
@ -7,7 +7,6 @@
|
||||
* Copyright (C) 2014 Ulrich Hecht
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
@ -15,6 +14,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/psci.h>
|
||||
|
@ -56,7 +56,6 @@ static const char *const sh73a0_boards_compat_dt[] __initconst = {
|
||||
DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)")
|
||||
.smp = smp_ops(sh73a0_smp_ops),
|
||||
.map_io = sh73a0_map_io,
|
||||
.init_early = shmobile_init_delay,
|
||||
.init_machine = sh73a0_generic_init,
|
||||
.init_late = shmobile_init_late,
|
||||
.dt_compat = sh73a0_boards_compat_dt,
|
||||
|
@ -181,12 +181,6 @@ static irqreturn_t spear_timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction spear_timer_irq = {
|
||||
.name = "timer",
|
||||
.flags = IRQF_TIMER,
|
||||
.handler = spear_timer_interrupt
|
||||
};
|
||||
|
||||
static void __init spear_clockevent_init(int irq)
|
||||
{
|
||||
u32 tick_rate;
|
||||
@ -201,7 +195,8 @@ static void __init spear_clockevent_init(int irq)
|
||||
|
||||
clockevents_config_and_register(&clkevt, tick_rate, 3, 0xfff0);
|
||||
|
||||
setup_irq(irq, &spear_timer_irq);
|
||||
if (request_irq(irq, spear_timer_interrupt, IRQF_TIMER, "timer", NULL))
|
||||
pr_err("Failed to request irq %d (timer)\n", irq);
|
||||
}
|
||||
|
||||
static const struct of_device_id timer_of_match[] __initconst = {
|
||||
|
@ -10,9 +10,9 @@
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset/sunxi.h>
|
||||
|
||||
|
@ -8,29 +8,14 @@ obj-y += reset.o
|
||||
obj-y += reset-handler.o
|
||||
obj-y += sleep.o
|
||||
obj-y += tegra.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
|
||||
obj-y += sleep-tegra20.o
|
||||
obj-y += sleep-tegra30.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
|
||||
endif
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o
|
||||
endif
|
||||
obj-$(CONFIG_SMP) += platsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
|
||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
|
||||
endif
|
||||
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += sleep-tegra30.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += pm-tegra30.o
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += cpuidle-tegra114.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-paz00.o
|
||||
|
@ -1,89 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <asm/firmware.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/firmware/trusted_foundations.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/psci.h>
|
||||
|
||||
#include "cpuidle.h"
|
||||
#include "pm.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#define TEGRA114_MAX_STATES 2
|
||||
#else
|
||||
#define TEGRA114_MAX_STATES 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int tegra114_idle_power_down(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
local_fiq_disable();
|
||||
|
||||
tegra_set_cpu_in_lp2();
|
||||
cpu_pm_enter();
|
||||
|
||||
call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
|
||||
|
||||
/* Do suspend by ourselves if the firmware does not implement it */
|
||||
if (call_firmware_op(do_idle, 0) == -ENOSYS)
|
||||
cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
|
||||
|
||||
cpu_pm_exit();
|
||||
tegra_clear_cpu_in_lp2();
|
||||
|
||||
local_fiq_enable();
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void tegra114_idle_enter_s2idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
tegra114_idle_power_down(dev, drv, index);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct cpuidle_driver tegra_idle_driver = {
|
||||
.name = "tegra_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.state_count = TEGRA114_MAX_STATES,
|
||||
.states = {
|
||||
[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
[1] = {
|
||||
.enter = tegra114_idle_power_down,
|
||||
.enter_s2idle = tegra114_idle_enter_s2idle,
|
||||
.exit_latency = 500,
|
||||
.target_residency = 1000,
|
||||
.flags = CPUIDLE_FLAG_TIMER_STOP,
|
||||
.power_usage = 0,
|
||||
.name = "powered-down",
|
||||
.desc = "CPU power gated",
|
||||
},
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
int __init tegra114_cpuidle_init(void)
|
||||
{
|
||||
if (!psci_smp_available())
|
||||
return cpuidle_register(&tegra_idle_driver, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* CPU idle driver for Tegra CPUs
|
||||
*
|
||||
* Copyright (c) 2010-2012, NVIDIA Corporation.
|
||||
* Copyright (c) 2011 Google, Inc.
|
||||
* Author: Colin Cross <ccross@android.com>
|
||||
* Gary King <gking@nvidia.com>
|
||||
*
|
||||
* Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <soc/tegra/flowctrl.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
#include "cpuidle.h"
|
||||
#include "iomap.h"
|
||||
#include "irq.h"
|
||||
#include "pm.h"
|
||||
#include "reset.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static bool abort_flag;
|
||||
static atomic_t abort_barrier;
|
||||
static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index);
|
||||
#define TEGRA20_MAX_STATES 2
|
||||
#else
|
||||
#define TEGRA20_MAX_STATES 1
|
||||
#endif
|
||||
|
||||
static struct cpuidle_driver tegra_idle_driver = {
|
||||
.name = "tegra_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.states = {
|
||||
ARM_CPUIDLE_WFI_STATE_PWR(600),
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
{
|
||||
.enter = tegra20_idle_lp2_coupled,
|
||||
.exit_latency = 5000,
|
||||
.target_residency = 10000,
|
||||
.power_usage = 0,
|
||||
.flags = CPUIDLE_FLAG_COUPLED |
|
||||
CPUIDLE_FLAG_TIMER_STOP,
|
||||
.name = "powered-down",
|
||||
.desc = "CPU power gated",
|
||||
},
|
||||
#endif
|
||||
},
|
||||
.state_count = TEGRA20_MAX_STATES,
|
||||
.safe_state_index = 0,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_SMP
|
||||
static int tegra20_reset_sleeping_cpu_1(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
tegra_pen_lock();
|
||||
|
||||
if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE)
|
||||
tegra20_cpu_shutdown(1);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
tegra_pen_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tegra20_wake_cpu1_from_reset(void)
|
||||
{
|
||||
tegra_pen_lock();
|
||||
|
||||
tegra20_cpu_clear_resettable();
|
||||
|
||||
/* enable cpu clock on cpu */
|
||||
tegra_enable_cpu_clock(1);
|
||||
|
||||
/* take the CPU out of reset */
|
||||
tegra_cpu_out_of_reset(1);
|
||||
|
||||
/* unhalt the cpu */
|
||||
flowctrl_write_cpu_halt(1, 0);
|
||||
|
||||
tegra_pen_unlock();
|
||||
}
|
||||
|
||||
static int tegra20_reset_cpu_1(void)
|
||||
{
|
||||
if (!cpu_online(1) || !tegra20_reset_sleeping_cpu_1())
|
||||
return 0;
|
||||
|
||||
tegra20_wake_cpu1_from_reset();
|
||||
return -EBUSY;
|
||||
}
|
||||
#else
|
||||
static inline void tegra20_wake_cpu1_from_reset(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int tegra20_reset_cpu_1(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
while (tegra20_cpu_is_resettable_soon())
|
||||
cpu_relax();
|
||||
|
||||
if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready())
|
||||
return false;
|
||||
|
||||
tegra_idle_lp2_last();
|
||||
|
||||
if (cpu_online(1))
|
||||
tegra20_wake_cpu1_from_reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
|
||||
|
||||
tegra20_cpu_clear_resettable();
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
bool entered_lp2 = false;
|
||||
|
||||
if (tegra_pending_sgi())
|
||||
WRITE_ONCE(abort_flag, true);
|
||||
|
||||
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
||||
|
||||
if (abort_flag) {
|
||||
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
||||
abort_flag = false; /* clean flag for next coming */
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
local_fiq_disable();
|
||||
|
||||
tegra_set_cpu_in_lp2();
|
||||
cpu_pm_enter();
|
||||
|
||||
if (dev->cpu == 0)
|
||||
entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index);
|
||||
else
|
||||
entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);
|
||||
|
||||
cpu_pm_exit();
|
||||
tegra_clear_cpu_in_lp2();
|
||||
|
||||
local_fiq_enable();
|
||||
|
||||
smp_rmb();
|
||||
|
||||
return entered_lp2 ? index : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tegra20 HW appears to have a bug such that PCIe device interrupts, whether
|
||||
* they are legacy IRQs or MSI, are lost when LP2 is enabled. To work around
|
||||
* this, simply disable LP2 if the PCI driver and DT node are both enabled.
|
||||
*/
|
||||
void tegra20_cpuidle_pcie_irqs_in_use(void)
|
||||
{
|
||||
pr_info_once(
|
||||
"Disabling cpuidle LP2 state, since PCIe IRQs are in use\n");
|
||||
cpuidle_driver_state_disabled(&tegra_idle_driver, 1, true);
|
||||
}
|
||||
|
||||
int __init tegra20_cpuidle_init(void)
|
||||
{
|
||||
return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* CPU idle driver for Tegra CPUs
|
||||
*
|
||||
* Copyright (c) 2010-2012, NVIDIA Corporation.
|
||||
* Copyright (c) 2011 Google, Inc.
|
||||
* Author: Colin Cross <ccross@android.com>
|
||||
* Gary King <gking@nvidia.com>
|
||||
*
|
||||
* Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
#include "cpuidle.h"
|
||||
#include "pm.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int tegra30_idle_lp2(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index);
|
||||
#endif
|
||||
|
||||
static struct cpuidle_driver tegra_idle_driver = {
|
||||
.name = "tegra_idle",
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.state_count = 2,
|
||||
#else
|
||||
.state_count = 1,
|
||||
#endif
|
||||
.states = {
|
||||
[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
[1] = {
|
||||
.enter = tegra30_idle_lp2,
|
||||
.exit_latency = 2000,
|
||||
.target_residency = 2200,
|
||||
.power_usage = 0,
|
||||
.flags = CPUIDLE_FLAG_TIMER_STOP,
|
||||
.name = "powered-down",
|
||||
.desc = "CPU power gated",
|
||||
},
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
/* All CPUs entering LP2 is not working.
|
||||
* Don't let CPU0 enter LP2 when any secondary CPU is online.
|
||||
*/
|
||||
if (num_online_cpus() > 1 || !tegra_cpu_rail_off_ready()) {
|
||||
cpu_do_idle();
|
||||
return false;
|
||||
}
|
||||
|
||||
tegra_idle_lp2_last();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
smp_wmb();
|
||||
|
||||
cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tegra30_idle_lp2(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
bool entered_lp2 = false;
|
||||
bool last_cpu;
|
||||
|
||||
local_fiq_disable();
|
||||
|
||||
last_cpu = tegra_set_cpu_in_lp2();
|
||||
cpu_pm_enter();
|
||||
|
||||
if (dev->cpu == 0) {
|
||||
if (last_cpu)
|
||||
entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv,
|
||||
index);
|
||||
else
|
||||
cpu_do_idle();
|
||||
} else {
|
||||
entered_lp2 = tegra30_cpu_core_power_down(dev, drv, index);
|
||||
}
|
||||
|
||||
cpu_pm_exit();
|
||||
tegra_clear_cpu_in_lp2();
|
||||
|
||||
local_fiq_enable();
|
||||
|
||||
smp_rmb();
|
||||
|
||||
return (entered_lp2) ? index : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int __init tegra30_cpuidle_init(void)
|
||||
{
|
||||
return cpuidle_register(&tegra_idle_driver, NULL);
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* arch/arm/mach-tegra/cpuidle.c
|
||||
*
|
||||
* CPU idle driver for Tegra CPUs
|
||||
*
|
||||
* Copyright (c) 2010-2012, NVIDIA Corporation.
|
||||
* Copyright (c) 2011 Google, Inc.
|
||||
* Author: Colin Cross <ccross@android.com>
|
||||
* Gary King <gking@nvidia.com>
|
||||
*
|
||||
* Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
||||
#include "cpuidle.h"
|
||||
|
||||
void __init tegra_cpuidle_init(void)
|
||||
{
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA20:
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
|
||||
tegra20_cpuidle_init();
|
||||
break;
|
||||
case TEGRA30:
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC))
|
||||
tegra30_cpuidle_init();
|
||||
break;
|
||||
case TEGRA114:
|
||||
case TEGRA124:
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
|
||||
IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
|
||||
tegra114_cpuidle_init();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void tegra_cpuidle_pcie_irqs_in_use(void)
|
||||
{
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA20:
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
|
||||
tegra20_cpuidle_pcie_irqs_in_use();
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __MACH_TEGRA_CPUIDLE_H
|
||||
#define __MACH_TEGRA_CPUIDLE_H
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
int tegra20_cpuidle_init(void);
|
||||
void tegra20_cpuidle_pcie_irqs_in_use(void);
|
||||
int tegra30_cpuidle_init(void);
|
||||
int tegra114_cpuidle_init(void);
|
||||
void tegra_cpuidle_init(void);
|
||||
void tegra_cpuidle_pcie_irqs_in_use(void);
|
||||
#else
|
||||
static inline void tegra_cpuidle_init(void) {}
|
||||
static inline void tegra_cpuidle_pcie_irqs_in_use(void) {}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -18,9 +18,10 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#include <soc/tegra/irq.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "iomap.h"
|
||||
#include "irq.h"
|
||||
|
||||
#define SGI_MASK 0xFFFF
|
||||
|
||||
|
@ -110,7 +110,7 @@ static void suspend_cpu_complex(void)
|
||||
flowctrl_cpu_suspend_enter(cpu);
|
||||
}
|
||||
|
||||
void tegra_clear_cpu_in_lp2(void)
|
||||
void tegra_pm_clear_cpu_in_lp2(void)
|
||||
{
|
||||
int phy_cpu_id = cpu_logical_map(smp_processor_id());
|
||||
u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
|
||||
@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
|
||||
spin_unlock(&tegra_lp2_lock);
|
||||
}
|
||||
|
||||
bool tegra_set_cpu_in_lp2(void)
|
||||
void tegra_pm_set_cpu_in_lp2(void)
|
||||
{
|
||||
int phy_cpu_id = cpu_logical_map(smp_processor_id());
|
||||
bool last_cpu = false;
|
||||
cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
|
||||
u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
|
||||
|
||||
spin_lock(&tegra_lp2_lock);
|
||||
@ -135,22 +133,15 @@ bool tegra_set_cpu_in_lp2(void)
|
||||
BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
|
||||
*cpu_in_lp2 |= BIT(phy_cpu_id);
|
||||
|
||||
if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
|
||||
last_cpu = true;
|
||||
else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1)
|
||||
tegra20_cpu_set_resettable_soon();
|
||||
|
||||
spin_unlock(&tegra_lp2_lock);
|
||||
return last_cpu;
|
||||
}
|
||||
|
||||
int tegra_cpu_do_idle(void)
|
||||
{
|
||||
return cpu_do_idle();
|
||||
}
|
||||
|
||||
static int tegra_sleep_cpu(unsigned long v2p)
|
||||
{
|
||||
if (tegra_cpu_car_ops->rail_off_ready &&
|
||||
WARN_ON(!tegra_cpu_rail_off_ready()))
|
||||
return -EBUSY;
|
||||
|
||||
/*
|
||||
* L2 cache disabling using kernel API only allowed when all
|
||||
* secondary CPU's are offline. Cache have to be disabled with
|
||||
@ -159,9 +150,10 @@ static int tegra_sleep_cpu(unsigned long v2p)
|
||||
* if any of secondary CPU's is online and this is the LP2-idle
|
||||
* code-path only for Tegra20/30.
|
||||
*/
|
||||
if (trusted_foundations_registered())
|
||||
outer_disable();
|
||||
|
||||
#ifdef CONFIG_OUTER_CACHE
|
||||
if (trusted_foundations_registered() && outer_cache.disable)
|
||||
outer_cache.disable();
|
||||
#endif
|
||||
/*
|
||||
* Note that besides of setting up CPU reset vector this firmware
|
||||
* call may also do the following, depending on the FW version:
|
||||
@ -202,14 +194,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
|
||||
tegra_pmc_enter_suspend_mode(mode);
|
||||
}
|
||||
|
||||
void tegra_idle_lp2_last(void)
|
||||
int tegra_pm_enter_lp2(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
tegra_pm_set(TEGRA_SUSPEND_LP2);
|
||||
|
||||
cpu_cluster_pm_enter();
|
||||
suspend_cpu_complex();
|
||||
|
||||
cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
|
||||
err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
|
||||
|
||||
/*
|
||||
* Resume L2 cache if it wasn't re-enabled early during resume,
|
||||
@ -221,6 +215,8 @@ void tegra_idle_lp2_last(void)
|
||||
|
||||
restore_cpu_complex();
|
||||
cpu_cluster_pm_exit();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
|
||||
@ -365,7 +361,7 @@ static int tegra_suspend_enter(suspend_state_t state)
|
||||
tegra_suspend_enter_lp1();
|
||||
break;
|
||||
case TEGRA_SUSPEND_LP2:
|
||||
tegra_set_cpu_in_lp2();
|
||||
tegra_pm_set_cpu_in_lp2();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -386,7 +382,7 @@ static int tegra_suspend_enter(suspend_state_t state)
|
||||
tegra_suspend_exit_lp1();
|
||||
break;
|
||||
case TEGRA_SUSPEND_LP2:
|
||||
tegra_clear_cpu_in_lp2();
|
||||
tegra_pm_clear_cpu_in_lp2();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -436,4 +432,18 @@ void __init tegra_init_suspend(void)
|
||||
|
||||
suspend_set_ops(&tegra_suspend_ops);
|
||||
}
|
||||
|
||||
int tegra_pm_park_secondary_cpu(unsigned long cpu)
|
||||
{
|
||||
if (cpu > 0) {
|
||||
tegra_disable_clean_inv_dcache(TEGRA_FLUSH_CACHE_LOUIS);
|
||||
|
||||
if (tegra_get_chip_id() == TEGRA20)
|
||||
tegra20_hotplug_shutdown();
|
||||
else
|
||||
tegra30_hotplug_shutdown();
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
@ -23,10 +23,6 @@ void tegra20_sleep_core_init(void);
|
||||
void tegra30_lp1_iram_hook(void);
|
||||
void tegra30_sleep_core_init(void);
|
||||
|
||||
void tegra_clear_cpu_in_lp2(void);
|
||||
bool tegra_set_cpu_in_lp2(void);
|
||||
int tegra_cpu_do_idle(void);
|
||||
void tegra_idle_lp2_last(void);
|
||||
extern void (*tegra_tear_down_cpu)(void);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
@ -183,17 +183,6 @@ after_errata:
|
||||
bleq __die @ CPU not present (to OS)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
/* Are we on Tegra20? */
|
||||
cmp r6, #TEGRA20
|
||||
bne 1f
|
||||
/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
|
||||
mov r0, #CPU_NOT_RESETTABLE
|
||||
cmp r10, #0
|
||||
strbne r0, [r12, #RESET_DATA(RESETTABLE_STATUS)]
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* Waking up from LP1? */
|
||||
ldr r8, [r12, #RESET_DATA(MASK_LP1)]
|
||||
tst r8, r11 @ if in_lp1
|
||||
|
@ -16,9 +16,8 @@
|
||||
#define TEGRA_RESET_STARTUP_SECONDARY 3
|
||||
#define TEGRA_RESET_STARTUP_LP2 4
|
||||
#define TEGRA_RESET_STARTUP_LP1 5
|
||||
#define TEGRA_RESET_RESETTABLE_STATUS 6
|
||||
#define TEGRA_RESET_TF_PRESENT 7
|
||||
#define TEGRA_RESET_DATA_SIZE 8
|
||||
#define TEGRA_RESET_TF_PRESENT 6
|
||||
#define TEGRA_RESET_DATA_SIZE 7
|
||||
|
||||
#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
|
||||
|
||||
@ -42,10 +41,6 @@ void __tegra_cpu_reset_handler_end(void);
|
||||
(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
|
||||
((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
|
||||
(u32)__tegra_cpu_reset_handler_start)))
|
||||
#define tegra20_cpu1_resettable_status \
|
||||
(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
|
||||
((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_RESETTABLE_STATUS] - \
|
||||
(u32)__tegra_cpu_reset_handler_start)))
|
||||
#endif
|
||||
|
||||
#define tegra_cpu_reset_handler_offset \
|
||||
|
@ -43,9 +43,6 @@
|
||||
#define APB_MISC_XM2CFGCPADCTRL2 0x8e4
|
||||
#define APB_MISC_XM2CFGDPADCTRL2 0x8e8
|
||||
|
||||
#define __tegra20_cpu1_resettable_status_offset \
|
||||
(__tegra_cpu_reset_handler_data_offset + RESET_DATA(RESETTABLE_STATUS))
|
||||
|
||||
.macro pll_enable, rd, r_car_base, pll_base
|
||||
ldr \rd, [\r_car_base, #\pll_base]
|
||||
tst \rd, #(1 << 30)
|
||||
@ -90,10 +87,6 @@ ENDPROC(tegra20_hotplug_shutdown)
|
||||
ENTRY(tegra20_cpu_shutdown)
|
||||
cmp r0, #0
|
||||
reteq lr @ must not be called for CPU 0
|
||||
mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
|
||||
ldr r2, =__tegra20_cpu1_resettable_status_offset
|
||||
mov r12, #CPU_RESETTABLE
|
||||
strb r12, [r1, r2]
|
||||
|
||||
cpu_to_halt_reg r1, r0
|
||||
ldr r3, =TEGRA_FLOW_CTRL_VIRT
|
||||
@ -116,107 +109,6 @@ ENDPROC(tegra20_cpu_shutdown)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/*
|
||||
* tegra_pen_lock
|
||||
*
|
||||
* spinlock implementation with no atomic test-and-set and no coherence
|
||||
* using Peterson's algorithm on strongly-ordered registers
|
||||
* used to synchronize a cpu waking up from wfi with entering lp2 on idle
|
||||
*
|
||||
* The reference link of Peterson's algorithm:
|
||||
* http://en.wikipedia.org/wiki/Peterson's_algorithm
|
||||
*
|
||||
* SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
|
||||
* on cpu 0:
|
||||
* r2 = flag[0] (in SCRATCH38)
|
||||
* r3 = flag[1] (in SCRATCH39)
|
||||
* on cpu1:
|
||||
* r2 = flag[1] (in SCRATCH39)
|
||||
* r3 = flag[0] (in SCRATCH38)
|
||||
*
|
||||
* must be called with MMU on
|
||||
* corrupts r0-r3, r12
|
||||
*/
|
||||
ENTRY(tegra_pen_lock)
|
||||
mov32 r3, TEGRA_PMC_VIRT
|
||||
cpu_id r0
|
||||
add r1, r3, #PMC_SCRATCH37
|
||||
cmp r0, #0
|
||||
addeq r2, r3, #PMC_SCRATCH38
|
||||
addeq r3, r3, #PMC_SCRATCH39
|
||||
addne r2, r3, #PMC_SCRATCH39
|
||||
addne r3, r3, #PMC_SCRATCH38
|
||||
|
||||
mov r12, #1
|
||||
str r12, [r2] @ flag[cpu] = 1
|
||||
dsb
|
||||
str r12, [r1] @ !turn = cpu
|
||||
1: dsb
|
||||
ldr r12, [r3]
|
||||
cmp r12, #1 @ flag[!cpu] == 1?
|
||||
ldreq r12, [r1]
|
||||
cmpeq r12, r0 @ !turn == cpu?
|
||||
beq 1b @ while !turn == cpu && flag[!cpu] == 1
|
||||
|
||||
ret lr @ locked
|
||||
ENDPROC(tegra_pen_lock)
|
||||
|
||||
ENTRY(tegra_pen_unlock)
|
||||
dsb
|
||||
mov32 r3, TEGRA_PMC_VIRT
|
||||
cpu_id r0
|
||||
cmp r0, #0
|
||||
addeq r2, r3, #PMC_SCRATCH38
|
||||
addne r2, r3, #PMC_SCRATCH39
|
||||
mov r12, #0
|
||||
str r12, [r2]
|
||||
ret lr
|
||||
ENDPROC(tegra_pen_unlock)
|
||||
|
||||
/*
|
||||
* tegra20_cpu_clear_resettable(void)
|
||||
*
|
||||
* Called to clear the "resettable soon" flag in IRAM variable when
|
||||
* it is expected that the secondary CPU will be idle soon.
|
||||
*/
|
||||
ENTRY(tegra20_cpu_clear_resettable)
|
||||
mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
|
||||
ldr r2, =__tegra20_cpu1_resettable_status_offset
|
||||
mov r12, #CPU_NOT_RESETTABLE
|
||||
strb r12, [r1, r2]
|
||||
ret lr
|
||||
ENDPROC(tegra20_cpu_clear_resettable)
|
||||
|
||||
/*
|
||||
* tegra20_cpu_set_resettable_soon(void)
|
||||
*
|
||||
* Called to set the "resettable soon" flag in IRAM variable when
|
||||
* it is expected that the secondary CPU will be idle soon.
|
||||
*/
|
||||
ENTRY(tegra20_cpu_set_resettable_soon)
|
||||
mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
|
||||
ldr r2, =__tegra20_cpu1_resettable_status_offset
|
||||
mov r12, #CPU_RESETTABLE_SOON
|
||||
strb r12, [r1, r2]
|
||||
ret lr
|
||||
ENDPROC(tegra20_cpu_set_resettable_soon)
|
||||
|
||||
/*
|
||||
* tegra20_cpu_is_resettable_soon(void)
|
||||
*
|
||||
* Returns true if the "resettable soon" flag in IRAM variable has been
|
||||
* set because it is expected that the secondary CPU will be idle soon.
|
||||
*/
|
||||
ENTRY(tegra20_cpu_is_resettable_soon)
|
||||
mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
|
||||
ldr r2, =__tegra20_cpu1_resettable_status_offset
|
||||
ldrb r12, [r1, r2]
|
||||
cmp r12, #CPU_RESETTABLE_SOON
|
||||
moveq r0, #1
|
||||
movne r0, #0
|
||||
ret lr
|
||||
ENDPROC(tegra20_cpu_is_resettable_soon)
|
||||
|
||||
/*
|
||||
* tegra20_sleep_core_finish(unsigned long v2p)
|
||||
*
|
||||
@ -242,68 +134,6 @@ ENTRY(tegra20_sleep_core_finish)
|
||||
ret r3
|
||||
ENDPROC(tegra20_sleep_core_finish)
|
||||
|
||||
/*
|
||||
* tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
|
||||
*
|
||||
* Enters WFI on secondary CPU by exiting coherency.
|
||||
*/
|
||||
ENTRY(tegra20_sleep_cpu_secondary_finish)
|
||||
stmfd sp!, {r4-r11, lr}
|
||||
|
||||
mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency
|
||||
|
||||
/* Flush and disable the L1 data cache */
|
||||
mov r0, #TEGRA_FLUSH_CACHE_LOUIS
|
||||
bl tegra_disable_clean_inv_dcache
|
||||
|
||||
mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT
|
||||
ldr r4, =__tegra20_cpu1_resettable_status_offset
|
||||
mov r3, #CPU_RESETTABLE
|
||||
strb r3, [r0, r4]
|
||||
|
||||
bl tegra_cpu_do_idle
|
||||
|
||||
/*
|
||||
* cpu may be reset while in wfi, which will return through
|
||||
* tegra_resume to cpu_resume
|
||||
* or interrupt may wake wfi, which will return here
|
||||
* cpu state is unchanged - MMU is on, cache is on, coherency
|
||||
* is off, and the data cache is off
|
||||
*
|
||||
* r11 contains the original actlr
|
||||
*/
|
||||
|
||||
bl tegra_pen_lock
|
||||
|
||||
mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT
|
||||
ldr r4, =__tegra20_cpu1_resettable_status_offset
|
||||
mov r3, #CPU_NOT_RESETTABLE
|
||||
strb r3, [r0, r4]
|
||||
|
||||
bl tegra_pen_unlock
|
||||
|
||||
/* Re-enable the data cache */
|
||||
mrc p15, 0, r10, c1, c0, 0
|
||||
orr r10, r10, #CR_C
|
||||
mcr p15, 0, r10, c1, c0, 0
|
||||
isb
|
||||
|
||||
mcr p15, 0, r11, c1, c0, 1 @ reenable coherency
|
||||
|
||||
/* Invalidate the TLBs & BTAC */
|
||||
mov r1, #0
|
||||
mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs
|
||||
mcr p15, 0, r1, c7, c1, 6 @ invalidate shared BTAC
|
||||
dsb
|
||||
isb
|
||||
|
||||
/* the cpu was running with coherency disabled,
|
||||
* caches may be out of date */
|
||||
bl v7_flush_kern_cache_louis
|
||||
|
||||
ldmfd sp!, {r4 - r11, pc}
|
||||
ENDPROC(tegra20_sleep_cpu_secondary_finish)
|
||||
|
||||
/*
|
||||
* tegra20_tear_down_cpu
|
||||
*
|
||||
|
@ -265,11 +265,11 @@ ENTRY(tegra30_sleep_core_finish)
|
||||
ENDPROC(tegra30_sleep_core_finish)
|
||||
|
||||
/*
|
||||
* tegra30_sleep_cpu_secondary_finish(unsigned long v2p)
|
||||
* tegra30_pm_secondary_cpu_suspend(unsigned long unused_arg)
|
||||
*
|
||||
* Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
|
||||
*/
|
||||
ENTRY(tegra30_sleep_cpu_secondary_finish)
|
||||
ENTRY(tegra30_pm_secondary_cpu_suspend)
|
||||
mov r7, lr
|
||||
|
||||
/* Flush and disable the L1 data cache */
|
||||
@ -281,7 +281,7 @@ ENTRY(tegra30_sleep_cpu_secondary_finish)
|
||||
bl tegra30_cpu_shutdown
|
||||
mov r0, #1 @ never return here
|
||||
ret r7
|
||||
ENDPROC(tegra30_sleep_cpu_secondary_finish)
|
||||
ENDPROC(tegra30_pm_secondary_cpu_suspend)
|
||||
|
||||
/*
|
||||
* tegra30_tear_down_cpu
|
||||
|
@ -114,29 +114,14 @@
|
||||
.endm
|
||||
|
||||
#else
|
||||
void tegra_pen_lock(void);
|
||||
void tegra_pen_unlock(void);
|
||||
void tegra_resume(void);
|
||||
int tegra_sleep_cpu_finish(unsigned long);
|
||||
void tegra_disable_clean_inv_dcache(u32 flag);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
void tegra20_hotplug_shutdown(void);
|
||||
void tegra30_hotplug_shutdown(void);
|
||||
#endif
|
||||
|
||||
void tegra20_cpu_shutdown(int cpu);
|
||||
int tegra20_cpu_is_resettable_soon(void);
|
||||
void tegra20_cpu_clear_resettable(void);
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
void tegra20_cpu_set_resettable_soon(void);
|
||||
#else
|
||||
static inline void tegra20_cpu_set_resettable_soon(void) {}
|
||||
#endif
|
||||
|
||||
int tegra20_sleep_cpu_secondary_finish(unsigned long);
|
||||
void tegra20_tear_down_cpu(void);
|
||||
int tegra30_sleep_cpu_secondary_finish(unsigned long);
|
||||
void tegra30_tear_down_cpu(void);
|
||||
|
||||
#endif
|
||||
|
@ -36,13 +36,12 @@
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/psci.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
#include "cpuidle.h"
|
||||
#include "iomap.h"
|
||||
#include "irq.h"
|
||||
#include "pm.h"
|
||||
#include "reset.h"
|
||||
#include "sleep.h"
|
||||
@ -86,7 +85,6 @@ static void __init tegra_dt_init(void)
|
||||
static void __init tegra_dt_init_late(void)
|
||||
{
|
||||
tegra_init_suspend();
|
||||
tegra_cpuidle_init();
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
|
||||
of_machine_is_compatible("compal,paz00"))
|
||||
@ -95,6 +93,9 @@ static void __init tegra_dt_init_late(void)
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
|
||||
of_machine_is_compatible("nvidia,tegra20"))
|
||||
platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0);
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available())
|
||||
platform_device_register_simple("tegra-cpuidle", -1, NULL, 0);
|
||||
}
|
||||
|
||||
static const char * const tegra_dt_board_compat[] = {
|
||||
|
@ -12,10 +12,10 @@
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/zynq.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -177,12 +177,6 @@ static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction orion_timer_irq = {
|
||||
.name = "orion_tick",
|
||||
.flags = IRQF_TIMER,
|
||||
.handler = orion_timer_interrupt
|
||||
};
|
||||
|
||||
void __init
|
||||
orion_time_set_base(void __iomem *_timer_base)
|
||||
{
|
||||
@ -236,7 +230,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
|
||||
/*
|
||||
* Setup clockevent timer (interrupt-driven).
|
||||
*/
|
||||
setup_irq(irq, &orion_timer_irq);
|
||||
if (request_irq(irq, orion_timer_interrupt, IRQF_TIMER, "orion_tick",
|
||||
NULL))
|
||||
pr_err("Failed to request irq %u (orion_tick)\n", irq);
|
||||
orion_clkevt.cpumask = cpumask_of(0);
|
||||
clockevents_config_and_register(&orion_clkevt, tclk, 1, 0xfffffffe);
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ config ARCH_BCM2835
|
||||
select ARM_AMBA
|
||||
select ARM_GIC
|
||||
select ARM_TIMER_SP804
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
help
|
||||
This enables support for the Broadcom BCM2837 and BCM2711 SoC.
|
||||
These SoCs are used in the Raspberry Pi 3 and 4 devices.
|
||||
@ -301,7 +300,6 @@ config ARCH_ZX
|
||||
|
||||
config ARCH_ZYNQMP
|
||||
bool "Xilinx ZynqMP Family"
|
||||
select ZYNQMP_FIRMWARE
|
||||
help
|
||||
This enables support for Xilinx ZynqMP Family
|
||||
|
||||
|
@ -14,27 +14,8 @@
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
#define PMC_PLL_CTRL0 0xc
|
||||
#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
|
||||
#define PMC_PLL_CTRL0_ENPLL BIT(28)
|
||||
#define PMC_PLL_CTRL0_ENPLLCK BIT(29)
|
||||
#define PMC_PLL_CTRL0_ENLOCK BIT(31)
|
||||
|
||||
#define PMC_PLL_CTRL1 0x10
|
||||
#define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0)
|
||||
#define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
|
||||
|
||||
#define PMC_PLL_ACR 0x18
|
||||
#define PMC_PLL_ACR_DEFAULT_UPLL 0x12020010UL
|
||||
#define PMC_PLL_ACR_DEFAULT_PLLA 0x00020010UL
|
||||
#define PMC_PLL_ACR_UTMIVR BIT(12)
|
||||
#define PMC_PLL_ACR_UTMIBG BIT(13)
|
||||
#define PMC_PLL_ACR_LOOP_FILTER_MSK GENMASK(31, 24)
|
||||
|
||||
#define PMC_PLL_UPDT 0x1c
|
||||
#define PMC_PLL_UPDT_UPDATE BIT(8)
|
||||
|
||||
#define PMC_PLL_ISR0 0xec
|
||||
#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
|
||||
#define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
|
||||
|
||||
#define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
|
||||
#define UPLL_DIV 2
|
||||
@ -59,7 +40,7 @@ static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
|
||||
{
|
||||
unsigned int status;
|
||||
|
||||
regmap_read(regmap, PMC_PLL_ISR0, &status);
|
||||
regmap_read(regmap, AT91_PMC_PLL_ISR0, &status);
|
||||
|
||||
return !!(status & BIT(id));
|
||||
}
|
||||
@ -74,12 +55,12 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(pll->lock, flags);
|
||||
regmap_write(regmap, PMC_PLL_UPDT, pll->id);
|
||||
regmap_write(regmap, AT91_PMC_PLL_UPDT, pll->id);
|
||||
|
||||
regmap_read(regmap, PMC_PLL_CTRL0, &val);
|
||||
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
|
||||
div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
|
||||
|
||||
regmap_read(regmap, PMC_PLL_CTRL1, &val);
|
||||
regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
|
||||
mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
|
||||
|
||||
if (sam9x60_pll_ready(regmap, pll->id) &&
|
||||
@ -88,39 +69,39 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Recommended value for PMC_PLL_ACR */
|
||||
/* Recommended value for AT91_PMC_PLL_ACR */
|
||||
if (pll->characteristics->upll)
|
||||
val = PMC_PLL_ACR_DEFAULT_UPLL;
|
||||
val = AT91_PMC_PLL_ACR_DEFAULT_UPLL;
|
||||
else
|
||||
val = PMC_PLL_ACR_DEFAULT_PLLA;
|
||||
regmap_write(regmap, PMC_PLL_ACR, val);
|
||||
val = AT91_PMC_PLL_ACR_DEFAULT_PLLA;
|
||||
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
|
||||
|
||||
regmap_write(regmap, PMC_PLL_CTRL1,
|
||||
regmap_write(regmap, AT91_PMC_PLL_CTRL1,
|
||||
FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul));
|
||||
|
||||
if (pll->characteristics->upll) {
|
||||
/* Enable the UTMI internal bandgap */
|
||||
val |= PMC_PLL_ACR_UTMIBG;
|
||||
regmap_write(regmap, PMC_PLL_ACR, val);
|
||||
val |= AT91_PMC_PLL_ACR_UTMIBG;
|
||||
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
|
||||
|
||||
udelay(10);
|
||||
|
||||
/* Enable the UTMI internal regulator */
|
||||
val |= PMC_PLL_ACR_UTMIVR;
|
||||
regmap_write(regmap, PMC_PLL_ACR, val);
|
||||
val |= AT91_PMC_PLL_ACR_UTMIVR;
|
||||
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
|
||||
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
regmap_update_bits(regmap, PMC_PLL_UPDT,
|
||||
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
|
||||
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
|
||||
AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
|
||||
|
||||
regmap_write(regmap, PMC_PLL_CTRL0,
|
||||
PMC_PLL_CTRL0_ENLOCK | PMC_PLL_CTRL0_ENPLL |
|
||||
PMC_PLL_CTRL0_ENPLLCK | pll->div);
|
||||
regmap_write(regmap, AT91_PMC_PLL_CTRL0,
|
||||
AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL |
|
||||
AT91_PMC_PLL_CTRL0_ENPLLCK | pll->div);
|
||||
|
||||
regmap_update_bits(regmap, PMC_PLL_UPDT,
|
||||
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
|
||||
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
|
||||
AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
|
||||
|
||||
while (!sam9x60_pll_ready(regmap, pll->id))
|
||||
cpu_relax();
|
||||
@ -144,22 +125,24 @@ static void sam9x60_pll_unprepare(struct clk_hw *hw)
|
||||
|
||||
spin_lock_irqsave(pll->lock, flags);
|
||||
|
||||
regmap_write(pll->regmap, PMC_PLL_UPDT, pll->id);
|
||||
regmap_write(pll->regmap, AT91_PMC_PLL_UPDT, pll->id);
|
||||
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_CTRL0,
|
||||
PMC_PLL_CTRL0_ENPLLCK, 0);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
|
||||
AT91_PMC_PLL_CTRL0_ENPLLCK, 0);
|
||||
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
|
||||
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
|
||||
AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
|
||||
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_CTRL0, PMC_PLL_CTRL0_ENPLL, 0);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
|
||||
AT91_PMC_PLL_CTRL0_ENPLL, 0);
|
||||
|
||||
if (pll->characteristics->upll)
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_ACR,
|
||||
PMC_PLL_ACR_UTMIBG | PMC_PLL_ACR_UTMIVR, 0);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_ACR,
|
||||
AT91_PMC_PLL_ACR_UTMIBG |
|
||||
AT91_PMC_PLL_ACR_UTMIVR, 0);
|
||||
|
||||
regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
|
||||
PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
|
||||
regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
|
||||
AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);
|
||||
|
||||
spin_unlock_irqrestore(pll->lock, flags);
|
||||
}
|
||||
@ -316,10 +299,10 @@ sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
|
||||
pll->regmap = regmap;
|
||||
pll->lock = lock;
|
||||
|
||||
regmap_write(regmap, PMC_PLL_UPDT, id);
|
||||
regmap_read(regmap, PMC_PLL_CTRL0, &pllr);
|
||||
regmap_write(regmap, AT91_PMC_PLL_UPDT, id);
|
||||
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &pllr);
|
||||
pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr);
|
||||
regmap_read(regmap, PMC_PLL_CTRL1, &pllr);
|
||||
regmap_read(regmap, AT91_PMC_PLL_CTRL1, &pllr);
|
||||
pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);
|
||||
|
||||
hw = &pll->hw;
|
||||
|
@ -86,3 +86,11 @@ config ARM_MVEBU_V7_CPUIDLE
|
||||
depends on (ARCH_MVEBU || COMPILE_TEST) && !ARM64
|
||||
help
|
||||
Select this to enable cpuidle on Armada 370, 38x and XP processors.
|
||||
|
||||
config ARM_TEGRA_CPUIDLE
|
||||
bool "CPU Idle Driver for NVIDIA Tegra SoCs"
|
||||
depends on ARCH_TEGRA && !ARM64
|
||||
select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
|
||||
select ARM_CPU_SUSPEND
|
||||
help
|
||||
Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs.
|
||||
|
@ -24,6 +24,7 @@ obj-$(CONFIG_ARM_CPUIDLE) += cpuidle-arm.o
|
||||
obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle_psci.o
|
||||
cpuidle_psci-y := cpuidle-psci.o
|
||||
cpuidle_psci-$(CONFIG_PM_GENERIC_DOMAINS_OF) += cpuidle-psci-domain.o
|
||||
obj-$(CONFIG_ARM_TEGRA_CPUIDLE) += cpuidle-tegra.o
|
||||
|
||||
###############################################################################
|
||||
# MIPS drivers
|
||||
|
392
drivers/cpuidle/cpuidle-tegra.c
Normal file
392
drivers/cpuidle/cpuidle-tegra.c
Normal file
@ -0,0 +1,392 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* CPU idle driver for Tegra CPUs
|
||||
*
|
||||
* Copyright (c) 2010-2013, NVIDIA Corporation.
|
||||
* Copyright (c) 2011 Google, Inc.
|
||||
* Author: Colin Cross <ccross@android.com>
|
||||
* Gary King <gking@nvidia.com>
|
||||
*
|
||||
* Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
|
||||
*
|
||||
* Tegra20/124 driver unification by Dmitry Osipenko <digetx@gmail.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "tegra-cpuidle: " fmt
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/firmware/trusted_foundations.h>
|
||||
|
||||
#include <soc/tegra/cpuidle.h>
|
||||
#include <soc/tegra/flowctrl.h>
|
||||
#include <soc/tegra/fuse.h>
|
||||
#include <soc/tegra/irq.h>
|
||||
#include <soc/tegra/pm.h>
|
||||
#include <soc/tegra/pmc.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
enum tegra_state {
|
||||
TEGRA_C1,
|
||||
TEGRA_C7,
|
||||
TEGRA_CC6,
|
||||
TEGRA_STATE_COUNT,
|
||||
};
|
||||
|
||||
static atomic_t tegra_idle_barrier;
|
||||
static atomic_t tegra_abort_flag;
|
||||
|
||||
static inline bool tegra_cpuidle_using_firmware(void)
|
||||
{
|
||||
return firmware_ops->prepare_idle && firmware_ops->do_idle;
|
||||
}
|
||||
|
||||
static void tegra_cpuidle_report_cpus_state(void)
|
||||
{
|
||||
unsigned long cpu, lcpu, csr;
|
||||
|
||||
for_each_cpu(lcpu, cpu_possible_mask) {
|
||||
cpu = cpu_logical_map(lcpu);
|
||||
csr = flowctrl_read_cpu_csr(cpu);
|
||||
|
||||
pr_err("cpu%lu: online=%d flowctrl_csr=0x%08lx\n",
|
||||
cpu, cpu_online(lcpu), csr);
|
||||
}
|
||||
}
|
||||
|
||||
static int tegra_cpuidle_wait_for_secondary_cpus_parking(void)
|
||||
{
|
||||
unsigned int retries = 3;
|
||||
|
||||
while (retries--) {
|
||||
unsigned int delay_us = 10;
|
||||
unsigned int timeout_us = 500 * 1000 / delay_us;
|
||||
|
||||
/*
|
||||
* The primary CPU0 core shall wait for the secondaries
|
||||
* shutdown in order to power-off CPU's cluster safely.
|
||||
* The timeout value depends on the current CPU frequency,
|
||||
* it takes about 40-150us in average and over 1000us in
|
||||
* a worst case scenario.
|
||||
*/
|
||||
do {
|
||||
if (tegra_cpu_rail_off_ready())
|
||||
return 0;
|
||||
|
||||
udelay(delay_us);
|
||||
|
||||
} while (timeout_us--);
|
||||
|
||||
pr_err("secondary CPU taking too long to park\n");
|
||||
|
||||
tegra_cpuidle_report_cpus_state();
|
||||
}
|
||||
|
||||
pr_err("timed out waiting secondaries to park\n");
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static void tegra_cpuidle_unpark_secondary_cpus(void)
|
||||
{
|
||||
unsigned int cpu, lcpu;
|
||||
|
||||
for_each_cpu(lcpu, cpu_online_mask) {
|
||||
cpu = cpu_logical_map(lcpu);
|
||||
|
||||
if (cpu > 0) {
|
||||
tegra_enable_cpu_clock(cpu);
|
||||
tegra_cpu_out_of_reset(cpu);
|
||||
flowctrl_write_cpu_halt(cpu, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int tegra_cpuidle_cc6_enter(unsigned int cpu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (cpu > 0) {
|
||||
ret = cpu_suspend(cpu, tegra_pm_park_secondary_cpu);
|
||||
} else {
|
||||
ret = tegra_cpuidle_wait_for_secondary_cpus_parking();
|
||||
if (!ret)
|
||||
ret = tegra_pm_enter_lp2();
|
||||
|
||||
tegra_cpuidle_unpark_secondary_cpus();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tegra_cpuidle_c7_enter(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (tegra_cpuidle_using_firmware()) {
|
||||
err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return call_firmware_op(do_idle, 0);
|
||||
}
|
||||
|
||||
return cpu_suspend(0, tegra30_pm_secondary_cpu_suspend);
|
||||
}
|
||||
|
||||
static int tegra_cpuidle_coupled_barrier(struct cpuidle_device *dev)
|
||||
{
|
||||
if (tegra_pending_sgi()) {
|
||||
/*
|
||||
* CPU got local interrupt that will be lost after GIC's
|
||||
* shutdown because GIC driver doesn't save/restore the
|
||||
* pending SGI state across CPU cluster PM. Abort and retry
|
||||
* next time.
|
||||
*/
|
||||
atomic_set(&tegra_abort_flag, 1);
|
||||
}
|
||||
|
||||
cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);
|
||||
|
||||
if (atomic_read(&tegra_abort_flag)) {
|
||||
cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);
|
||||
atomic_set(&tegra_abort_flag, 0);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,
|
||||
int index, unsigned int cpu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* CC6 state is the "CPU cluster power-off" state. In order to
|
||||
* enter this state, at first the secondary CPU cores need to be
|
||||
* parked into offline mode, then the last CPU should clean out
|
||||
* remaining dirty cache lines into DRAM and trigger Flow Controller
|
||||
* logic that turns off the cluster's power domain (which includes
|
||||
* CPU cores, GIC and L2 cache).
|
||||
*/
|
||||
if (index == TEGRA_CC6) {
|
||||
ret = tegra_cpuidle_coupled_barrier(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
local_fiq_disable();
|
||||
tegra_pm_set_cpu_in_lp2();
|
||||
cpu_pm_enter();
|
||||
|
||||
switch (index) {
|
||||
case TEGRA_C7:
|
||||
ret = tegra_cpuidle_c7_enter();
|
||||
break;
|
||||
|
||||
case TEGRA_CC6:
|
||||
ret = tegra_cpuidle_cc6_enter(cpu);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
cpu_pm_exit();
|
||||
tegra_pm_clear_cpu_in_lp2();
|
||||
local_fiq_enable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tegra_cpuidle_adjust_state_index(int index, unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
* On Tegra30 CPU0 can't be power-gated separately from secondary
|
||||
* cores because it gates the whole CPU cluster.
|
||||
*/
|
||||
if (cpu > 0 || index != TEGRA_C7 || tegra_get_chip_id() != TEGRA30)
|
||||
return index;
|
||||
|
||||
/* put CPU0 into C1 if C7 is requested and secondaries are online */
|
||||
if (!IS_ENABLED(CONFIG_PM_SLEEP) || num_online_cpus() > 1)
|
||||
index = TEGRA_C1;
|
||||
else
|
||||
index = TEGRA_CC6;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static int tegra_cpuidle_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
unsigned int cpu = cpu_logical_map(dev->cpu);
|
||||
int err;
|
||||
|
||||
index = tegra_cpuidle_adjust_state_index(index, cpu);
|
||||
if (dev->states_usage[index].disable)
|
||||
return -1;
|
||||
|
||||
if (index == TEGRA_C1)
|
||||
err = arm_cpuidle_simple_enter(dev, drv, index);
|
||||
else
|
||||
err = tegra_cpuidle_state_enter(dev, index, cpu);
|
||||
|
||||
if (err && (err != -EINTR || index != TEGRA_CC6))
|
||||
pr_err_once("failed to enter state %d err: %d\n", index, err);
|
||||
|
||||
return err ? -1 : index;
|
||||
}
|
||||
|
||||
static void tegra114_enter_s2idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
tegra_cpuidle_enter(dev, drv, index);
|
||||
}
|
||||
|
||||
/*
|
||||
* The previous versions of Tegra CPUIDLE driver used a different "legacy"
|
||||
* terminology for naming of the idling states, while this driver uses the
|
||||
* new terminology.
|
||||
*
|
||||
* Mapping of the old terms into the new ones:
|
||||
*
|
||||
* Old | New
|
||||
* ---------
|
||||
* LP3 | C1 (CPU core clock gating)
|
||||
* LP2 | C7 (CPU core power gating)
|
||||
* LP2 | CC6 (CPU cluster power gating)
|
||||
*
|
||||
* Note that that the older CPUIDLE driver versions didn't explicitly
|
||||
* differentiate the LP2 states because these states either used the same
|
||||
* code path or because CC6 wasn't supported.
|
||||
*/
|
||||
static struct cpuidle_driver tegra_idle_driver = {
|
||||
.name = "tegra_idle",
|
||||
.states = {
|
||||
[TEGRA_C1] = ARM_CPUIDLE_WFI_STATE_PWR(600),
|
||||
[TEGRA_C7] = {
|
||||
.enter = tegra_cpuidle_enter,
|
||||
.exit_latency = 2000,
|
||||
.target_residency = 2200,
|
||||
.power_usage = 100,
|
||||
.flags = CPUIDLE_FLAG_TIMER_STOP,
|
||||
.name = "C7",
|
||||
.desc = "CPU core powered off",
|
||||
},
|
||||
[TEGRA_CC6] = {
|
||||
.enter = tegra_cpuidle_enter,
|
||||
.exit_latency = 5000,
|
||||
.target_residency = 10000,
|
||||
.power_usage = 0,
|
||||
.flags = CPUIDLE_FLAG_TIMER_STOP |
|
||||
CPUIDLE_FLAG_COUPLED,
|
||||
.name = "CC6",
|
||||
.desc = "CPU cluster powered off",
|
||||
},
|
||||
},
|
||||
.state_count = TEGRA_STATE_COUNT,
|
||||
.safe_state_index = TEGRA_C1,
|
||||
};
|
||||
|
||||
static inline void tegra_cpuidle_disable_state(enum tegra_state state)
|
||||
{
|
||||
cpuidle_driver_state_disabled(&tegra_idle_driver, state, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tegra20 HW appears to have a bug such that PCIe device interrupts, whether
|
||||
* they are legacy IRQs or MSI, are lost when CC6 is enabled. To work around
|
||||
* this, simply disable CC6 if the PCI driver and DT node are both enabled.
|
||||
*/
|
||||
void tegra_cpuidle_pcie_irqs_in_use(void)
|
||||
{
|
||||
struct cpuidle_state *state_cc6 = &tegra_idle_driver.states[TEGRA_CC6];
|
||||
|
||||
if ((state_cc6->flags & CPUIDLE_FLAG_UNUSABLE) ||
|
||||
tegra_get_chip_id() != TEGRA20)
|
||||
return;
|
||||
|
||||
pr_info("disabling CC6 state, since PCIe IRQs are in use\n");
|
||||
tegra_cpuidle_disable_state(TEGRA_CC6);
|
||||
}
|
||||
|
||||
static void tegra_cpuidle_setup_tegra114_c7_state(void)
|
||||
{
|
||||
struct cpuidle_state *s = &tegra_idle_driver.states[TEGRA_C7];
|
||||
|
||||
s->enter_s2idle = tegra114_enter_s2idle;
|
||||
s->target_residency = 1000;
|
||||
s->exit_latency = 500;
|
||||
}
|
||||
|
||||
static int tegra_cpuidle_probe(struct platform_device *pdev)
|
||||
{
|
||||
/* LP2 could be disabled in device-tree */
|
||||
if (tegra_pmc_get_suspend_mode() < TEGRA_SUSPEND_LP2)
|
||||
tegra_cpuidle_disable_state(TEGRA_CC6);
|
||||
|
||||
/*
|
||||
* Required suspend-resume functionality, which is provided by the
|
||||
* Tegra-arch core and PMC driver, is unavailable if PM-sleep option
|
||||
* is disabled.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_PM_SLEEP)) {
|
||||
if (!tegra_cpuidle_using_firmware())
|
||||
tegra_cpuidle_disable_state(TEGRA_C7);
|
||||
|
||||
tegra_cpuidle_disable_state(TEGRA_CC6);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic WFI state (also known as C1 or LP3) and the coupled CPU
|
||||
* cluster power-off (CC6 or LP2) states are common for all Tegra SoCs.
|
||||
*/
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA20:
|
||||
/* Tegra20 isn't capable to power-off individual CPU cores */
|
||||
tegra_cpuidle_disable_state(TEGRA_C7);
|
||||
break;
|
||||
|
||||
case TEGRA30:
|
||||
tegra_cpuidle_disable_state(TEGRA_CC6);
|
||||
break;
|
||||
|
||||
case TEGRA114:
|
||||
case TEGRA124:
|
||||
tegra_cpuidle_setup_tegra114_c7_state();
|
||||
|
||||
/* coupled CC6 (LP2) state isn't implemented yet */
|
||||
tegra_cpuidle_disable_state(TEGRA_CC6);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
|
||||
}
|
||||
|
||||
static struct platform_driver tegra_cpuidle_driver = {
|
||||
.probe = tegra_cpuidle_probe,
|
||||
.driver = {
|
||||
.name = "tegra-cpuidle",
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(tegra_cpuidle_driver);
|
@ -6,6 +6,8 @@ menu "Zynq MPSoC Firmware Drivers"
|
||||
|
||||
config ZYNQMP_FIRMWARE
|
||||
bool "Enable Xilinx Zynq MPSoC firmware interface"
|
||||
depends on ARCH_ZYNQMP
|
||||
default y if ARCH_ZYNQMP
|
||||
select MFD_CORE
|
||||
help
|
||||
Firmware interface driver is used by different
|
||||
|
@ -78,6 +78,7 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 timeout)
|
||||
client->pkt_cnt = 0;
|
||||
client->client.dev = dev;
|
||||
client->client.tx_block = false;
|
||||
client->client.knows_txdone = true;
|
||||
client->chan = mbox_request_channel(&client->client, index);
|
||||
|
||||
if (IS_ERR(client->chan)) {
|
||||
|
@ -111,6 +111,28 @@ enum dew_regs {
|
||||
PWRAP_RG_SPI_CON13,
|
||||
PWRAP_SPISLV_KEY,
|
||||
|
||||
/* MT6359 only regs */
|
||||
PWRAP_DEW_CRC_SWRST,
|
||||
PWRAP_DEW_RG_EN_RECORD,
|
||||
PWRAP_DEW_RECORD_CMD0,
|
||||
PWRAP_DEW_RECORD_CMD1,
|
||||
PWRAP_DEW_RECORD_CMD2,
|
||||
PWRAP_DEW_RECORD_CMD3,
|
||||
PWRAP_DEW_RECORD_CMD4,
|
||||
PWRAP_DEW_RECORD_CMD5,
|
||||
PWRAP_DEW_RECORD_WDATA0,
|
||||
PWRAP_DEW_RECORD_WDATA1,
|
||||
PWRAP_DEW_RECORD_WDATA2,
|
||||
PWRAP_DEW_RECORD_WDATA3,
|
||||
PWRAP_DEW_RECORD_WDATA4,
|
||||
PWRAP_DEW_RECORD_WDATA5,
|
||||
PWRAP_DEW_RG_ADDR_TARGET,
|
||||
PWRAP_DEW_RG_ADDR_MASK,
|
||||
PWRAP_DEW_RG_WDATA_TARGET,
|
||||
PWRAP_DEW_RG_WDATA_MASK,
|
||||
PWRAP_DEW_RG_SPI_RECORD_CLR,
|
||||
PWRAP_DEW_RG_CMD_ALERT_CLR,
|
||||
|
||||
/* MT6397 only regs */
|
||||
PWRAP_DEW_EVENT_OUT_EN,
|
||||
PWRAP_DEW_EVENT_SRC_EN,
|
||||
@ -197,6 +219,42 @@ static const u32 mt6358_regs[] = {
|
||||
[PWRAP_SPISLV_KEY] = 0x044a,
|
||||
};
|
||||
|
||||
static const u32 mt6359_regs[] = {
|
||||
[PWRAP_DEW_RG_EN_RECORD] = 0x040a,
|
||||
[PWRAP_DEW_DIO_EN] = 0x040c,
|
||||
[PWRAP_DEW_READ_TEST] = 0x040e,
|
||||
[PWRAP_DEW_WRITE_TEST] = 0x0410,
|
||||
[PWRAP_DEW_CRC_SWRST] = 0x0412,
|
||||
[PWRAP_DEW_CRC_EN] = 0x0414,
|
||||
[PWRAP_DEW_CRC_VAL] = 0x0416,
|
||||
[PWRAP_DEW_CIPHER_KEY_SEL] = 0x0418,
|
||||
[PWRAP_DEW_CIPHER_IV_SEL] = 0x041a,
|
||||
[PWRAP_DEW_CIPHER_EN] = 0x041c,
|
||||
[PWRAP_DEW_CIPHER_RDY] = 0x041e,
|
||||
[PWRAP_DEW_CIPHER_MODE] = 0x0420,
|
||||
[PWRAP_DEW_CIPHER_SWRST] = 0x0422,
|
||||
[PWRAP_DEW_RDDMY_NO] = 0x0424,
|
||||
[PWRAP_DEW_RECORD_CMD0] = 0x0428,
|
||||
[PWRAP_DEW_RECORD_CMD1] = 0x042a,
|
||||
[PWRAP_DEW_RECORD_CMD2] = 0x042c,
|
||||
[PWRAP_DEW_RECORD_CMD3] = 0x042e,
|
||||
[PWRAP_DEW_RECORD_CMD4] = 0x0430,
|
||||
[PWRAP_DEW_RECORD_CMD5] = 0x0432,
|
||||
[PWRAP_DEW_RECORD_WDATA0] = 0x0434,
|
||||
[PWRAP_DEW_RECORD_WDATA1] = 0x0436,
|
||||
[PWRAP_DEW_RECORD_WDATA2] = 0x0438,
|
||||
[PWRAP_DEW_RECORD_WDATA3] = 0x043a,
|
||||
[PWRAP_DEW_RECORD_WDATA4] = 0x043c,
|
||||
[PWRAP_DEW_RECORD_WDATA5] = 0x043e,
|
||||
[PWRAP_DEW_RG_ADDR_TARGET] = 0x0440,
|
||||
[PWRAP_DEW_RG_ADDR_MASK] = 0x0442,
|
||||
[PWRAP_DEW_RG_WDATA_TARGET] = 0x0444,
|
||||
[PWRAP_DEW_RG_WDATA_MASK] = 0x0446,
|
||||
[PWRAP_DEW_RG_SPI_RECORD_CLR] = 0x0448,
|
||||
[PWRAP_DEW_RG_CMD_ALERT_CLR] = 0x0448,
|
||||
[PWRAP_SPISLV_KEY] = 0x044a,
|
||||
};
|
||||
|
||||
static const u32 mt6397_regs[] = {
|
||||
[PWRAP_DEW_BASE] = 0xbc00,
|
||||
[PWRAP_DEW_EVENT_OUT_EN] = 0xbc00,
|
||||
@ -497,6 +555,45 @@ static int mt6765_regs[] = {
|
||||
[PWRAP_DCM_DBC_PRD] = 0x1E0,
|
||||
};
|
||||
|
||||
static int mt6779_regs[] = {
|
||||
[PWRAP_MUX_SEL] = 0x0,
|
||||
[PWRAP_WRAP_EN] = 0x4,
|
||||
[PWRAP_DIO_EN] = 0x8,
|
||||
[PWRAP_RDDMY] = 0x20,
|
||||
[PWRAP_CSHEXT_WRITE] = 0x24,
|
||||
[PWRAP_CSHEXT_READ] = 0x28,
|
||||
[PWRAP_CSLEXT_WRITE] = 0x2C,
|
||||
[PWRAP_CSLEXT_READ] = 0x30,
|
||||
[PWRAP_EXT_CK_WRITE] = 0x34,
|
||||
[PWRAP_STAUPD_CTRL] = 0x3C,
|
||||
[PWRAP_STAUPD_GRPEN] = 0x40,
|
||||
[PWRAP_EINT_STA0_ADR] = 0x44,
|
||||
[PWRAP_HARB_HPRIO] = 0x68,
|
||||
[PWRAP_HIPRIO_ARB_EN] = 0x6C,
|
||||
[PWRAP_MAN_EN] = 0x7C,
|
||||
[PWRAP_MAN_CMD] = 0x80,
|
||||
[PWRAP_WACS0_EN] = 0x8C,
|
||||
[PWRAP_INIT_DONE0] = 0x90,
|
||||
[PWRAP_WACS1_EN] = 0x94,
|
||||
[PWRAP_WACS2_EN] = 0x9C,
|
||||
[PWRAP_INIT_DONE1] = 0x98,
|
||||
[PWRAP_INIT_DONE2] = 0xA0,
|
||||
[PWRAP_INT_EN] = 0xBC,
|
||||
[PWRAP_INT_FLG_RAW] = 0xC0,
|
||||
[PWRAP_INT_FLG] = 0xC4,
|
||||
[PWRAP_INT_CLR] = 0xC8,
|
||||
[PWRAP_INT1_EN] = 0xCC,
|
||||
[PWRAP_INT1_FLG] = 0xD4,
|
||||
[PWRAP_INT1_CLR] = 0xD8,
|
||||
[PWRAP_TIMER_EN] = 0xF0,
|
||||
[PWRAP_WDT_UNIT] = 0xF8,
|
||||
[PWRAP_WDT_SRC_EN] = 0xFC,
|
||||
[PWRAP_WDT_SRC_EN_1] = 0x100,
|
||||
[PWRAP_WACS2_CMD] = 0xC20,
|
||||
[PWRAP_WACS2_RDATA] = 0xC24,
|
||||
[PWRAP_WACS2_VLDCLR] = 0xC28,
|
||||
};
|
||||
|
||||
static int mt6797_regs[] = {
|
||||
[PWRAP_MUX_SEL] = 0x0,
|
||||
[PWRAP_WRAP_EN] = 0x4,
|
||||
@ -938,6 +1035,7 @@ enum pmic_type {
|
||||
PMIC_MT6351,
|
||||
PMIC_MT6357,
|
||||
PMIC_MT6358,
|
||||
PMIC_MT6359,
|
||||
PMIC_MT6380,
|
||||
PMIC_MT6397,
|
||||
};
|
||||
@ -945,6 +1043,7 @@ enum pmic_type {
|
||||
enum pwrap_type {
|
||||
PWRAP_MT2701,
|
||||
PWRAP_MT6765,
|
||||
PWRAP_MT6779,
|
||||
PWRAP_MT6797,
|
||||
PWRAP_MT7622,
|
||||
PWRAP_MT8135,
|
||||
@ -1377,6 +1476,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
break;
|
||||
case PWRAP_MT2701:
|
||||
case PWRAP_MT6765:
|
||||
case PWRAP_MT6779:
|
||||
case PWRAP_MT6797:
|
||||
case PWRAP_MT8173:
|
||||
case PWRAP_MT8516:
|
||||
@ -1711,6 +1811,15 @@ static const struct pwrap_slv_type pmic_mt6358 = {
|
||||
.pwrap_write = pwrap_write16,
|
||||
};
|
||||
|
||||
static const struct pwrap_slv_type pmic_mt6359 = {
|
||||
.dew_regs = mt6359_regs,
|
||||
.type = PMIC_MT6359,
|
||||
.regmap = &pwrap_regmap_config16,
|
||||
.caps = PWRAP_SLV_CAP_DUALIO,
|
||||
.pwrap_read = pwrap_read16,
|
||||
.pwrap_write = pwrap_write16,
|
||||
};
|
||||
|
||||
static const struct pwrap_slv_type pmic_mt6380 = {
|
||||
.dew_regs = NULL,
|
||||
.type = PMIC_MT6380,
|
||||
@ -1743,6 +1852,9 @@ static const struct of_device_id of_slave_match_tbl[] = {
|
||||
}, {
|
||||
.compatible = "mediatek,mt6358",
|
||||
.data = &pmic_mt6358,
|
||||
}, {
|
||||
.compatible = "mediatek,mt6359",
|
||||
.data = &pmic_mt6359,
|
||||
}, {
|
||||
/* The MT6380 PMIC only implements a regulator, so we bind it
|
||||
* directly instead of using a MFD.
|
||||
@ -1783,6 +1895,19 @@ static const struct pmic_wrapper_type pwrap_mt6765 = {
|
||||
.init_soc_specific = NULL,
|
||||
};
|
||||
|
||||
static const struct pmic_wrapper_type pwrap_mt6779 = {
|
||||
.regs = mt6779_regs,
|
||||
.type = PWRAP_MT6779,
|
||||
.arb_en_all = 0xfbb7f,
|
||||
.int_en_all = 0xfffffffe,
|
||||
.int1_en_all = 0,
|
||||
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
|
||||
.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
|
||||
.caps = 0,
|
||||
.init_reg_clock = pwrap_common_init_reg_clock,
|
||||
.init_soc_specific = NULL,
|
||||
};
|
||||
|
||||
static const struct pmic_wrapper_type pwrap_mt6797 = {
|
||||
.regs = mt6797_regs,
|
||||
.type = PWRAP_MT6797,
|
||||
@ -1867,6 +1992,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
|
||||
}, {
|
||||
.compatible = "mediatek,mt6765-pwrap",
|
||||
.data = &pwrap_mt6765,
|
||||
}, {
|
||||
.compatible = "mediatek,mt6779-pwrap",
|
||||
.data = &pwrap_mt6779,
|
||||
}, {
|
||||
.compatible = "mediatek,mt6797-pwrap",
|
||||
.data = &pwrap_mt6797,
|
||||
|
@ -116,6 +116,7 @@ config ARCH_R8A7779
|
||||
bool "R-Car H1 (R8A77790)"
|
||||
select ARCH_RCAR_GEN1
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_GLOBAL_TIMER
|
||||
select HAVE_ARM_SCU if SMP
|
||||
select HAVE_ARM_TWD if SMP
|
||||
select SYSC_R8A7779
|
||||
@ -163,6 +164,7 @@ config ARCH_SH73A0
|
||||
bool "SH-Mobile AG5 (R8A73A00)"
|
||||
select ARCH_RMOBILE
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_GLOBAL_TIMER
|
||||
select HAVE_ARM_SCU if SMP
|
||||
select HAVE_ARM_TWD if SMP
|
||||
select RENESAS_INTC_IRQPIN
|
||||
|
@ -3,7 +3,7 @@
|
||||
* drivers/soc/tegra/pmc.c
|
||||
*
|
||||
* Copyright (c) 2010 Google, Inc
|
||||
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Author:
|
||||
* Colin Cross <ccross@google.com>
|
||||
@ -13,9 +13,13 @@
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk/clk-conf.h>
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
@ -48,6 +52,7 @@
|
||||
#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
|
||||
#include <dt-bindings/gpio/tegra186-gpio.h>
|
||||
#include <dt-bindings/gpio/tegra194-gpio.h>
|
||||
#include <dt-bindings/soc/tegra-pmc.h>
|
||||
|
||||
#define PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
|
||||
@ -57,12 +62,15 @@
|
||||
#define PMC_CNTRL_SYSCLK_OE BIT(11) /* system clock enable */
|
||||
#define PMC_CNTRL_SYSCLK_POLARITY BIT(10) /* sys clk polarity */
|
||||
#define PMC_CNTRL_PWRREQ_POLARITY BIT(8)
|
||||
#define PMC_CNTRL_BLINK_EN 7
|
||||
#define PMC_CNTRL_MAIN_RST BIT(4)
|
||||
|
||||
#define PMC_WAKE_MASK 0x0c
|
||||
#define PMC_WAKE_LEVEL 0x10
|
||||
#define PMC_WAKE_STATUS 0x14
|
||||
#define PMC_SW_WAKE_STATUS 0x18
|
||||
#define PMC_DPD_PADS_ORIDE 0x1c
|
||||
#define PMC_DPD_PADS_ORIDE_BLINK 20
|
||||
|
||||
#define DPD_SAMPLE 0x020
|
||||
#define DPD_SAMPLE_ENABLE BIT(0)
|
||||
@ -75,6 +83,7 @@
|
||||
|
||||
#define PWRGATE_STATUS 0x38
|
||||
|
||||
#define PMC_BLINK_TIMER 0x40
|
||||
#define PMC_IMPL_E_33V_PWR 0x40
|
||||
|
||||
#define PMC_PWR_DET 0x48
|
||||
@ -100,6 +109,8 @@
|
||||
#define PMC_WAKE2_STATUS 0x168
|
||||
#define PMC_SW_WAKE2_STATUS 0x16c
|
||||
|
||||
#define PMC_CLK_OUT_CNTRL 0x1a8
|
||||
#define PMC_CLK_OUT_MUX_MASK GENMASK(1, 0)
|
||||
#define PMC_SENSOR_CTRL 0x1b0
|
||||
#define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2)
|
||||
#define PMC_SENSOR_CTRL_ENABLE_RST BIT(1)
|
||||
@ -155,6 +166,71 @@
|
||||
#define TEGRA_SMC_PMC_READ 0xaa
|
||||
#define TEGRA_SMC_PMC_WRITE 0xbb
|
||||
|
||||
struct pmc_clk {
|
||||
struct clk_hw hw;
|
||||
unsigned long offs;
|
||||
u32 mux_shift;
|
||||
u32 force_en_shift;
|
||||
};
|
||||
|
||||
#define to_pmc_clk(_hw) container_of(_hw, struct pmc_clk, hw)
|
||||
|
||||
struct pmc_clk_gate {
|
||||
struct clk_hw hw;
|
||||
unsigned long offs;
|
||||
u32 shift;
|
||||
};
|
||||
|
||||
#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
|
||||
|
||||
struct pmc_clk_init_data {
|
||||
char *name;
|
||||
const char *const *parents;
|
||||
int num_parents;
|
||||
int clk_id;
|
||||
u8 mux_shift;
|
||||
u8 force_en_shift;
|
||||
};
|
||||
|
||||
static const char * const clk_out1_parents[] = { "osc", "osc_div2",
|
||||
"osc_div4", "extern1",
|
||||
};
|
||||
|
||||
static const char * const clk_out2_parents[] = { "osc", "osc_div2",
|
||||
"osc_div4", "extern2",
|
||||
};
|
||||
|
||||
static const char * const clk_out3_parents[] = { "osc", "osc_div2",
|
||||
"osc_div4", "extern3",
|
||||
};
|
||||
|
||||
static const struct pmc_clk_init_data tegra_pmc_clks_data[] = {
|
||||
{
|
||||
.name = "pmc_clk_out_1",
|
||||
.parents = clk_out1_parents,
|
||||
.num_parents = ARRAY_SIZE(clk_out1_parents),
|
||||
.clk_id = TEGRA_PMC_CLK_OUT_1,
|
||||
.mux_shift = 6,
|
||||
.force_en_shift = 2,
|
||||
},
|
||||
{
|
||||
.name = "pmc_clk_out_2",
|
||||
.parents = clk_out2_parents,
|
||||
.num_parents = ARRAY_SIZE(clk_out2_parents),
|
||||
.clk_id = TEGRA_PMC_CLK_OUT_2,
|
||||
.mux_shift = 14,
|
||||
.force_en_shift = 10,
|
||||
},
|
||||
{
|
||||
.name = "pmc_clk_out_3",
|
||||
.parents = clk_out3_parents,
|
||||
.num_parents = ARRAY_SIZE(clk_out3_parents),
|
||||
.clk_id = TEGRA_PMC_CLK_OUT_3,
|
||||
.mux_shift = 22,
|
||||
.force_en_shift = 18,
|
||||
},
|
||||
};
|
||||
|
||||
struct tegra_powergate {
|
||||
struct generic_pm_domain genpd;
|
||||
struct tegra_pmc *pmc;
|
||||
@ -254,6 +330,10 @@ struct tegra_pmc_soc {
|
||||
*/
|
||||
const struct tegra_wake_event *wake_events;
|
||||
unsigned int num_wake_events;
|
||||
|
||||
const struct pmc_clk_init_data *pmc_clks_data;
|
||||
unsigned int num_pmc_clks;
|
||||
bool has_blink_output;
|
||||
};
|
||||
|
||||
static const char * const tegra186_reset_sources[] = {
|
||||
@ -2163,6 +2243,258 @@ static int tegra_pmc_clk_notify_cb(struct notifier_block *nb,
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static void pmc_clk_fence_udelay(u32 offset)
|
||||
{
|
||||
tegra_pmc_readl(pmc, offset);
|
||||
/* pmc clk propagation delay 2 us */
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
static u8 pmc_clk_mux_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct pmc_clk *clk = to_pmc_clk(hw);
|
||||
u32 val;
|
||||
|
||||
val = tegra_pmc_readl(pmc, clk->offs) >> clk->mux_shift;
|
||||
val &= PMC_CLK_OUT_MUX_MASK;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int pmc_clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct pmc_clk *clk = to_pmc_clk(hw);
|
||||
u32 val;
|
||||
|
||||
val = tegra_pmc_readl(pmc, clk->offs);
|
||||
val &= ~(PMC_CLK_OUT_MUX_MASK << clk->mux_shift);
|
||||
val |= index << clk->mux_shift;
|
||||
tegra_pmc_writel(pmc, val, clk->offs);
|
||||
pmc_clk_fence_udelay(clk->offs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pmc_clk_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct pmc_clk *clk = to_pmc_clk(hw);
|
||||
u32 val;
|
||||
|
||||
val = tegra_pmc_readl(pmc, clk->offs) & BIT(clk->force_en_shift);
|
||||
|
||||
return val ? 1 : 0;
|
||||
}
|
||||
|
||||
static void pmc_clk_set_state(unsigned long offs, u32 shift, int state)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = tegra_pmc_readl(pmc, offs);
|
||||
val = state ? (val | BIT(shift)) : (val & ~BIT(shift));
|
||||
tegra_pmc_writel(pmc, val, offs);
|
||||
pmc_clk_fence_udelay(offs);
|
||||
}
|
||||
|
||||
static int pmc_clk_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct pmc_clk *clk = to_pmc_clk(hw);
|
||||
|
||||
pmc_clk_set_state(clk->offs, clk->force_en_shift, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pmc_clk_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct pmc_clk *clk = to_pmc_clk(hw);
|
||||
|
||||
pmc_clk_set_state(clk->offs, clk->force_en_shift, 0);
|
||||
}
|
||||
|
||||
static const struct clk_ops pmc_clk_ops = {
|
||||
.get_parent = pmc_clk_mux_get_parent,
|
||||
.set_parent = pmc_clk_mux_set_parent,
|
||||
.determine_rate = __clk_mux_determine_rate,
|
||||
.is_enabled = pmc_clk_is_enabled,
|
||||
.enable = pmc_clk_enable,
|
||||
.disable = pmc_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk *
|
||||
tegra_pmc_clk_out_register(struct tegra_pmc *pmc,
|
||||
const struct pmc_clk_init_data *data,
|
||||
unsigned long offset)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct pmc_clk *pmc_clk;
|
||||
|
||||
pmc_clk = devm_kzalloc(pmc->dev, sizeof(*pmc_clk), GFP_KERNEL);
|
||||
if (!pmc_clk)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = data->name;
|
||||
init.ops = &pmc_clk_ops;
|
||||
init.parent_names = data->parents;
|
||||
init.num_parents = data->num_parents;
|
||||
init.flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
|
||||
CLK_SET_PARENT_GATE;
|
||||
|
||||
pmc_clk->hw.init = &init;
|
||||
pmc_clk->offs = offset;
|
||||
pmc_clk->mux_shift = data->mux_shift;
|
||||
pmc_clk->force_en_shift = data->force_en_shift;
|
||||
|
||||
return clk_register(NULL, &pmc_clk->hw);
|
||||
}
|
||||
|
||||
static int pmc_clk_gate_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
|
||||
|
||||
return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int pmc_clk_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
|
||||
|
||||
pmc_clk_set_state(gate->offs, gate->shift, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pmc_clk_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
|
||||
|
||||
pmc_clk_set_state(gate->offs, gate->shift, 0);
|
||||
}
|
||||
|
||||
static const struct clk_ops pmc_clk_gate_ops = {
|
||||
.is_enabled = pmc_clk_gate_is_enabled,
|
||||
.enable = pmc_clk_gate_enable,
|
||||
.disable = pmc_clk_gate_disable,
|
||||
};
|
||||
|
||||
static struct clk *
|
||||
tegra_pmc_clk_gate_register(struct tegra_pmc *pmc, const char *name,
|
||||
const char *parent_name, unsigned long offset,
|
||||
u32 shift)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct pmc_clk_gate *gate;
|
||||
|
||||
gate = devm_kzalloc(pmc->dev, sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &pmc_clk_gate_ops;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
init.flags = 0;
|
||||
|
||||
gate->hw.init = &init;
|
||||
gate->offs = offset;
|
||||
gate->shift = shift;
|
||||
|
||||
return clk_register(NULL, &gate->hw);
|
||||
}
|
||||
|
||||
static void tegra_pmc_clock_register(struct tegra_pmc *pmc,
|
||||
struct device_node *np)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_onecell_data *clk_data;
|
||||
unsigned int num_clks;
|
||||
int i, err;
|
||||
|
||||
num_clks = pmc->soc->num_pmc_clks;
|
||||
if (pmc->soc->has_blink_output)
|
||||
num_clks += 1;
|
||||
|
||||
if (!num_clks)
|
||||
return;
|
||||
|
||||
clk_data = devm_kmalloc(pmc->dev, sizeof(*clk_data), GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return;
|
||||
|
||||
clk_data->clks = devm_kcalloc(pmc->dev, TEGRA_PMC_CLK_MAX,
|
||||
sizeof(*clk_data->clks), GFP_KERNEL);
|
||||
if (!clk_data->clks)
|
||||
return;
|
||||
|
||||
clk_data->clk_num = TEGRA_PMC_CLK_MAX;
|
||||
|
||||
for (i = 0; i < TEGRA_PMC_CLK_MAX; i++)
|
||||
clk_data->clks[i] = ERR_PTR(-ENOENT);
|
||||
|
||||
for (i = 0; i < pmc->soc->num_pmc_clks; i++) {
|
||||
const struct pmc_clk_init_data *data;
|
||||
|
||||
data = pmc->soc->pmc_clks_data + i;
|
||||
|
||||
clk = tegra_pmc_clk_out_register(pmc, data, PMC_CLK_OUT_CNTRL);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_warn(pmc->dev, "unable to register clock %s: %d\n",
|
||||
data->name, PTR_ERR_OR_ZERO(clk));
|
||||
return;
|
||||
}
|
||||
|
||||
err = clk_register_clkdev(clk, data->name, NULL);
|
||||
if (err) {
|
||||
dev_warn(pmc->dev,
|
||||
"unable to register %s clock lookup: %d\n",
|
||||
data->name, err);
|
||||
return;
|
||||
}
|
||||
|
||||
clk_data->clks[data->clk_id] = clk;
|
||||
}
|
||||
|
||||
if (pmc->soc->has_blink_output) {
|
||||
tegra_pmc_writel(pmc, 0x0, PMC_BLINK_TIMER);
|
||||
clk = tegra_pmc_clk_gate_register(pmc,
|
||||
"pmc_blink_override",
|
||||
"clk_32k",
|
||||
PMC_DPD_PADS_ORIDE,
|
||||
PMC_DPD_PADS_ORIDE_BLINK);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_warn(pmc->dev,
|
||||
"unable to register pmc_blink_override: %d\n",
|
||||
PTR_ERR_OR_ZERO(clk));
|
||||
return;
|
||||
}
|
||||
|
||||
clk = tegra_pmc_clk_gate_register(pmc, "pmc_blink",
|
||||
"pmc_blink_override",
|
||||
PMC_CNTRL,
|
||||
PMC_CNTRL_BLINK_EN);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_warn(pmc->dev,
|
||||
"unable to register pmc_blink: %d\n",
|
||||
PTR_ERR_OR_ZERO(clk));
|
||||
return;
|
||||
}
|
||||
|
||||
err = clk_register_clkdev(clk, "pmc_blink", NULL);
|
||||
if (err) {
|
||||
dev_warn(pmc->dev,
|
||||
"unable to register pmc_blink lookup: %d\n",
|
||||
err);
|
||||
return;
|
||||
}
|
||||
|
||||
clk_data->clks[TEGRA_PMC_CLK_BLINK] = clk;
|
||||
}
|
||||
|
||||
err = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
|
||||
if (err)
|
||||
dev_warn(pmc->dev, "failed to add pmc clock provider: %d\n",
|
||||
err);
|
||||
}
|
||||
|
||||
static int tegra_pmc_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *base;
|
||||
@ -2281,6 +2613,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||
pmc->base = base;
|
||||
mutex_unlock(&pmc->powergates_lock);
|
||||
|
||||
tegra_pmc_clock_register(pmc, pdev->dev.of_node);
|
||||
platform_set_drvdata(pdev, pmc);
|
||||
|
||||
return 0;
|
||||
@ -2422,6 +2755,9 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
|
||||
.num_reset_sources = 0,
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
.pmc_clks_data = NULL,
|
||||
.num_pmc_clks = 0,
|
||||
.has_blink_output = true,
|
||||
};
|
||||
|
||||
static const char * const tegra30_powergates[] = {
|
||||
@ -2469,6 +2805,9 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
|
||||
.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
.pmc_clks_data = tegra_pmc_clks_data,
|
||||
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
|
||||
.has_blink_output = true,
|
||||
};
|
||||
|
||||
static const char * const tegra114_powergates[] = {
|
||||
@ -2520,6 +2859,9 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
|
||||
.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
.pmc_clks_data = tegra_pmc_clks_data,
|
||||
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
|
||||
.has_blink_output = true,
|
||||
};
|
||||
|
||||
static const char * const tegra124_powergates[] = {
|
||||
@ -2569,38 +2911,38 @@ static const u8 tegra124_cpu_powergates[] = {
|
||||
.name = (_name) \
|
||||
})
|
||||
|
||||
#define TEGRA124_IO_PAD_TABLE(_pad) \
|
||||
/* .id .dpd .voltage .name */ \
|
||||
_pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
|
||||
_pad(TEGRA_IO_PAD_BB, 15, UINT_MAX, "bb"), \
|
||||
_pad(TEGRA_IO_PAD_CAM, 36, UINT_MAX, "cam"), \
|
||||
_pad(TEGRA_IO_PAD_COMP, 22, UINT_MAX, "comp"), \
|
||||
_pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
|
||||
_pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csb"), \
|
||||
_pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "cse"), \
|
||||
_pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
|
||||
_pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \
|
||||
_pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \
|
||||
_pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \
|
||||
_pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
|
||||
_pad(TEGRA_IO_PAD_HV, 38, UINT_MAX, "hv"), \
|
||||
_pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \
|
||||
_pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
|
||||
_pad(TEGRA_IO_PAD_NAND, 13, UINT_MAX, "nand"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC1, 33, UINT_MAX, "sdmmc1"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC3, 34, UINT_MAX, "sdmmc3"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC4, 35, UINT_MAX, "sdmmc4"), \
|
||||
_pad(TEGRA_IO_PAD_SYS_DDC, 58, UINT_MAX, "sys_ddc"), \
|
||||
_pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
|
||||
_pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
|
||||
_pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
|
||||
_pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
|
||||
_pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb_bias")
|
||||
#define TEGRA124_IO_PAD_TABLE(_pad) \
|
||||
/* .id .dpd .voltage .name */ \
|
||||
_pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
|
||||
_pad(TEGRA_IO_PAD_BB, 15, UINT_MAX, "bb"), \
|
||||
_pad(TEGRA_IO_PAD_CAM, 36, UINT_MAX, "cam"), \
|
||||
_pad(TEGRA_IO_PAD_COMP, 22, UINT_MAX, "comp"), \
|
||||
_pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
|
||||
_pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csb"), \
|
||||
_pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "cse"), \
|
||||
_pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
|
||||
_pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \
|
||||
_pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \
|
||||
_pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \
|
||||
_pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
|
||||
_pad(TEGRA_IO_PAD_HV, 38, UINT_MAX, "hv"), \
|
||||
_pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \
|
||||
_pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
|
||||
_pad(TEGRA_IO_PAD_NAND, 13, UINT_MAX, "nand"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC1, 33, UINT_MAX, "sdmmc1"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC3, 34, UINT_MAX, "sdmmc3"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC4, 35, UINT_MAX, "sdmmc4"), \
|
||||
_pad(TEGRA_IO_PAD_SYS_DDC, 58, UINT_MAX, "sys_ddc"), \
|
||||
_pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
|
||||
_pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
|
||||
_pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
|
||||
_pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
|
||||
_pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb_bias")
|
||||
|
||||
static const struct tegra_io_pad_soc tegra124_io_pads[] = {
|
||||
TEGRA124_IO_PAD_TABLE(TEGRA_IO_PAD)
|
||||
@ -2631,6 +2973,9 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
|
||||
.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
.pmc_clks_data = tegra_pmc_clks_data,
|
||||
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
|
||||
.has_blink_output = true,
|
||||
};
|
||||
|
||||
static const char * const tegra210_powergates[] = {
|
||||
@ -2667,46 +3012,46 @@ static const u8 tegra210_cpu_powergates[] = {
|
||||
TEGRA_POWERGATE_CPU3,
|
||||
};
|
||||
|
||||
#define TEGRA210_IO_PAD_TABLE(_pad) \
|
||||
/* .id .dpd .voltage .name */ \
|
||||
_pad(TEGRA_IO_PAD_AUDIO, 17, 5, "audio"), \
|
||||
_pad(TEGRA_IO_PAD_AUDIO_HV, 61, 18, "audio-hv"), \
|
||||
_pad(TEGRA_IO_PAD_CAM, 36, 10, "cam"), \
|
||||
_pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
|
||||
_pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
|
||||
_pad(TEGRA_IO_PAD_CSIC, 42, UINT_MAX, "csic"), \
|
||||
_pad(TEGRA_IO_PAD_CSID, 43, UINT_MAX, "csid"), \
|
||||
_pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "csie"), \
|
||||
_pad(TEGRA_IO_PAD_CSIF, 45, UINT_MAX, "csif"), \
|
||||
_pad(TEGRA_IO_PAD_DBG, 25, 19, "dbg"), \
|
||||
_pad(TEGRA_IO_PAD_DEBUG_NONAO, 26, UINT_MAX, "debug-nonao"), \
|
||||
_pad(TEGRA_IO_PAD_DMIC, 50, 20, "dmic"), \
|
||||
_pad(TEGRA_IO_PAD_DP, 51, UINT_MAX, "dp"), \
|
||||
_pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
|
||||
_pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \
|
||||
_pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \
|
||||
_pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \
|
||||
_pad(TEGRA_IO_PAD_EMMC, 35, UINT_MAX, "emmc"), \
|
||||
_pad(TEGRA_IO_PAD_EMMC2, 37, UINT_MAX, "emmc2"), \
|
||||
_pad(TEGRA_IO_PAD_GPIO, 27, 21, "gpio"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \
|
||||
_pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
|
||||
_pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \
|
||||
_pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, 11, "pex-cntrl"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC1, 33, 12, "sdmmc1"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC3, 34, 13, "sdmmc3"), \
|
||||
_pad(TEGRA_IO_PAD_SPI, 46, 22, "spi"), \
|
||||
_pad(TEGRA_IO_PAD_SPI_HV, 47, 23, "spi-hv"), \
|
||||
_pad(TEGRA_IO_PAD_UART, 14, 2, "uart"), \
|
||||
_pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
|
||||
_pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
|
||||
_pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
|
||||
_pad(TEGRA_IO_PAD_USB3, 18, UINT_MAX, "usb3"), \
|
||||
_pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias")
|
||||
#define TEGRA210_IO_PAD_TABLE(_pad) \
|
||||
/* .id .dpd .voltage .name */ \
|
||||
_pad(TEGRA_IO_PAD_AUDIO, 17, 5, "audio"), \
|
||||
_pad(TEGRA_IO_PAD_AUDIO_HV, 61, 18, "audio-hv"), \
|
||||
_pad(TEGRA_IO_PAD_CAM, 36, 10, "cam"), \
|
||||
_pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
|
||||
_pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
|
||||
_pad(TEGRA_IO_PAD_CSIC, 42, UINT_MAX, "csic"), \
|
||||
_pad(TEGRA_IO_PAD_CSID, 43, UINT_MAX, "csid"), \
|
||||
_pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "csie"), \
|
||||
_pad(TEGRA_IO_PAD_CSIF, 45, UINT_MAX, "csif"), \
|
||||
_pad(TEGRA_IO_PAD_DBG, 25, 19, "dbg"), \
|
||||
_pad(TEGRA_IO_PAD_DEBUG_NONAO, 26, UINT_MAX, "debug-nonao"), \
|
||||
_pad(TEGRA_IO_PAD_DMIC, 50, 20, "dmic"), \
|
||||
_pad(TEGRA_IO_PAD_DP, 51, UINT_MAX, "dp"), \
|
||||
_pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
|
||||
_pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \
|
||||
_pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \
|
||||
_pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \
|
||||
_pad(TEGRA_IO_PAD_EMMC, 35, UINT_MAX, "emmc"), \
|
||||
_pad(TEGRA_IO_PAD_EMMC2, 37, UINT_MAX, "emmc2"), \
|
||||
_pad(TEGRA_IO_PAD_GPIO, 27, 21, "gpio"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \
|
||||
_pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
|
||||
_pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \
|
||||
_pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, 11, "pex-cntrl"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC1, 33, 12, "sdmmc1"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC3, 34, 13, "sdmmc3"), \
|
||||
_pad(TEGRA_IO_PAD_SPI, 46, 22, "spi"), \
|
||||
_pad(TEGRA_IO_PAD_SPI_HV, 47, 23, "spi-hv"), \
|
||||
_pad(TEGRA_IO_PAD_UART, 14, 2, "uart"), \
|
||||
_pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
|
||||
_pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
|
||||
_pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
|
||||
_pad(TEGRA_IO_PAD_USB3, 18, UINT_MAX, "usb3"), \
|
||||
_pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias")
|
||||
|
||||
static const struct tegra_io_pad_soc tegra210_io_pads[] = {
|
||||
TEGRA210_IO_PAD_TABLE(TEGRA_IO_PAD)
|
||||
@ -2745,48 +3090,51 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
|
||||
.num_reset_levels = 0,
|
||||
.num_wake_events = ARRAY_SIZE(tegra210_wake_events),
|
||||
.wake_events = tegra210_wake_events,
|
||||
.pmc_clks_data = tegra_pmc_clks_data,
|
||||
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
|
||||
.has_blink_output = true,
|
||||
};
|
||||
|
||||
#define TEGRA186_IO_PAD_TABLE(_pad) \
|
||||
/* .id .dpd .voltage .name */ \
|
||||
_pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
|
||||
_pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
|
||||
_pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
|
||||
_pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \
|
||||
_pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
|
||||
_pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
|
||||
_pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
|
||||
_pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias"), \
|
||||
_pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
|
||||
_pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
|
||||
_pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
|
||||
_pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC2_HV, 34, 5, "sdmmc2-hv"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \
|
||||
_pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \
|
||||
_pad(TEGRA_IO_PAD_DSIB, 40, UINT_MAX, "dsib"), \
|
||||
_pad(TEGRA_IO_PAD_DSIC, 41, UINT_MAX, "dsic"), \
|
||||
_pad(TEGRA_IO_PAD_DSID, 42, UINT_MAX, "dsid"), \
|
||||
_pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \
|
||||
_pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \
|
||||
_pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \
|
||||
_pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \
|
||||
_pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \
|
||||
_pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \
|
||||
_pad(TEGRA_IO_PAD_DMIC_HV, 52, 2, "dmic-hv"), \
|
||||
_pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \
|
||||
_pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \
|
||||
_pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \
|
||||
_pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv")
|
||||
#define TEGRA186_IO_PAD_TABLE(_pad) \
|
||||
/* .id .dpd .voltage .name */ \
|
||||
_pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
|
||||
_pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
|
||||
_pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
|
||||
_pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \
|
||||
_pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
|
||||
_pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
|
||||
_pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
|
||||
_pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias"), \
|
||||
_pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
|
||||
_pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
|
||||
_pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
|
||||
_pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC2_HV, 34, 5, "sdmmc2-hv"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \
|
||||
_pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \
|
||||
_pad(TEGRA_IO_PAD_DSIB, 40, UINT_MAX, "dsib"), \
|
||||
_pad(TEGRA_IO_PAD_DSIC, 41, UINT_MAX, "dsic"), \
|
||||
_pad(TEGRA_IO_PAD_DSID, 42, UINT_MAX, "dsid"), \
|
||||
_pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \
|
||||
_pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \
|
||||
_pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \
|
||||
_pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \
|
||||
_pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \
|
||||
_pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \
|
||||
_pad(TEGRA_IO_PAD_DMIC_HV, 52, 2, "dmic-hv"), \
|
||||
_pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \
|
||||
_pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \
|
||||
_pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \
|
||||
_pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv")
|
||||
|
||||
static const struct tegra_io_pad_soc tegra186_io_pads[] = {
|
||||
TEGRA186_IO_PAD_TABLE(TEGRA_IO_PAD)
|
||||
@ -2874,56 +3222,69 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
|
||||
.num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
|
||||
.num_wake_events = ARRAY_SIZE(tegra186_wake_events),
|
||||
.wake_events = tegra186_wake_events,
|
||||
.pmc_clks_data = NULL,
|
||||
.num_pmc_clks = 0,
|
||||
.has_blink_output = false,
|
||||
};
|
||||
|
||||
#define TEGRA194_IO_PAD_TABLE(_pad) \
|
||||
/* .id .dpd .voltage .name */ \
|
||||
_pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
|
||||
_pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
|
||||
_pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \
|
||||
_pad(TEGRA_IO_PAD_EQOS, 8, UINT_MAX, "eqos"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK_2_BIAS, 9, UINT_MAX, "pex-clk-2-bias"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CLK_2, 10, UINT_MAX, "pex-clk-2"), \
|
||||
_pad(TEGRA_IO_PAD_DAP3, 11, UINT_MAX, "dap3"), \
|
||||
_pad(TEGRA_IO_PAD_DAP5, 12, UINT_MAX, "dap5"), \
|
||||
_pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
|
||||
_pad(TEGRA_IO_PAD_PWR_CTL, 15, UINT_MAX, "pwr-ctl"), \
|
||||
_pad(TEGRA_IO_PAD_SOC_GPIO53, 16, UINT_MAX, "soc-gpio53"), \
|
||||
_pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
|
||||
_pad(TEGRA_IO_PAD_GP_PWM2, 18, UINT_MAX, "gp-pwm2"), \
|
||||
_pad(TEGRA_IO_PAD_GP_PWM3, 19, UINT_MAX, "gp-pwm3"), \
|
||||
_pad(TEGRA_IO_PAD_SOC_GPIO12, 20, UINT_MAX, "soc-gpio12"), \
|
||||
_pad(TEGRA_IO_PAD_SOC_GPIO13, 21, UINT_MAX, "soc-gpio13"), \
|
||||
_pad(TEGRA_IO_PAD_SOC_GPIO10, 22, UINT_MAX, "soc-gpio10"), \
|
||||
_pad(TEGRA_IO_PAD_UART4, 23, UINT_MAX, "uart4"), \
|
||||
_pad(TEGRA_IO_PAD_UART5, 24, UINT_MAX, "uart5"), \
|
||||
_pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI_DP3, 26, UINT_MAX, "hdmi-dp3"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI_DP2, 27, UINT_MAX, "hdmi-dp2"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \
|
||||
_pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_CTL2, 33, UINT_MAX, "pex-ctl2"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_L0_RST_N, 34, UINT_MAX, "pex-l0-rst"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_L1_RST_N, 35, UINT_MAX, "pex-l1-rst"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \
|
||||
_pad(TEGRA_IO_PAD_PEX_L5_RST_N, 37, UINT_MAX, "pex-l5-rst"), \
|
||||
_pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \
|
||||
_pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \
|
||||
_pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \
|
||||
_pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \
|
||||
_pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \
|
||||
_pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \
|
||||
_pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \
|
||||
_pad(TEGRA_IO_PAD_CSIG, 50, UINT_MAX, "csig"), \
|
||||
_pad(TEGRA_IO_PAD_CSIH, 51, UINT_MAX, "csih"), \
|
||||
_pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \
|
||||
_pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \
|
||||
_pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \
|
||||
_pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \
|
||||
_pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv")
|
||||
|
||||
static const struct tegra_io_pad_soc tegra194_io_pads[] = {
|
||||
{ .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK_BIAS, .dpd = 4, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK3, .dpd = 5, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 7, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_EQOS, .dpd = 8, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK2_BIAS, .dpd = 9, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 10, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_DAP3, .dpd = 11, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_DAP5, .dpd = 12, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PWR_CTL, .dpd = 15, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SOC_GPIO53, .dpd = 16, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_GP_PWM2, .dpd = 18, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_GP_PWM3, .dpd = 19, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SOC_GPIO12, .dpd = 20, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SOC_GPIO13, .dpd = 21, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SOC_GPIO10, .dpd = 22, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_UART4, .dpd = 23, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_UART5, .dpd = 24, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_HDMI_DP3, .dpd = 26, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_HDMI_DP2, .dpd = 27, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_HDMI_DP0, .dpd = 28, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_HDMI_DP1, .dpd = 29, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CTL2, .dpd = 33, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_L0_RST_N, .dpd = 34, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_L1_RST_N, .dpd = 35, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SDMMC4, .dpd = 36, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_L5_RST_N, .dpd = 37, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIC, .dpd = 43, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSID, .dpd = 44, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIE, .dpd = 45, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIF, .dpd = 46, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SPI, .dpd = 47, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_UFS, .dpd = 49, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIG, .dpd = 50, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIH, .dpd = 51, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_EDP, .dpd = 53, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SDMMC1_HV, .dpd = 55, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SDMMC3_HV, .dpd = 56, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CONN, .dpd = 60, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = UINT_MAX },
|
||||
TEGRA194_IO_PAD_TABLE(TEGRA_IO_PAD)
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc tegra194_pin_descs[] = {
|
||||
TEGRA194_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
|
||||
};
|
||||
|
||||
static const struct tegra_pmc_regs tegra194_pmc_regs = {
|
||||
@ -2976,10 +3337,12 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
|
||||
.has_tsense_reset = false,
|
||||
.has_gpu_clamps = false,
|
||||
.needs_mbist_war = false,
|
||||
.has_impl_33v_pwr = false,
|
||||
.has_impl_33v_pwr = true,
|
||||
.maybe_tz_only = false,
|
||||
.num_io_pads = ARRAY_SIZE(tegra194_io_pads),
|
||||
.io_pads = tegra194_io_pads,
|
||||
.num_pin_descs = ARRAY_SIZE(tegra194_pin_descs),
|
||||
.pin_descs = tegra194_pin_descs,
|
||||
.regs = &tegra194_pmc_regs,
|
||||
.init = NULL,
|
||||
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
|
||||
@ -2991,6 +3354,9 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
|
||||
.num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
|
||||
.num_wake_events = ARRAY_SIZE(tegra194_wake_events),
|
||||
.wake_events = tegra194_wake_events,
|
||||
.pmc_clks_data = NULL,
|
||||
.num_pmc_clks = 0,
|
||||
.has_blink_output = false,
|
||||
};
|
||||
|
||||
static const struct of_device_id tegra_pmc_match[] = {
|
||||
|
@ -130,6 +130,19 @@ static int am33xx_push_sram_idle(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int am33xx_do_sram_idle(u32 wfi_flags)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!m3_ipc || !pm_ops)
|
||||
return 0;
|
||||
|
||||
if (wfi_flags & WFI_FLAG_WAKE_M3)
|
||||
ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_IDLE);
|
||||
|
||||
return pm_ops->cpu_suspend(am33xx_do_wfi_sram, wfi_flags);
|
||||
}
|
||||
|
||||
static int __init am43xx_map_gic(void)
|
||||
{
|
||||
gic_dist_base = ioremap(AM43XX_GIC_DIST_BASE, SZ_4K);
|
||||
@ -260,6 +273,8 @@ static int am33xx_pm_begin(suspend_state_t state)
|
||||
rtc_only_idle = 0;
|
||||
}
|
||||
|
||||
pm_ops->begin_suspend();
|
||||
|
||||
switch (state) {
|
||||
case PM_SUSPEND_MEM:
|
||||
ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_DEEPSLEEP);
|
||||
@ -301,6 +316,8 @@ static void am33xx_pm_end(void)
|
||||
}
|
||||
|
||||
rtc_only_idle = 0;
|
||||
|
||||
pm_ops->finish_suspend();
|
||||
}
|
||||
|
||||
static int am33xx_pm_valid(suspend_state_t state)
|
||||
@ -503,7 +520,7 @@ static int am33xx_pm_probe(struct platform_device *pdev)
|
||||
suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
|
||||
#endif /* CONFIG_SUSPEND */
|
||||
|
||||
ret = pm_ops->init();
|
||||
ret = pm_ops->init(am33xx_do_sram_idle);
|
||||
if (ret) {
|
||||
dev_err(dev, "Unable to call core pm init!\n");
|
||||
ret = -ENODEV;
|
||||
@ -522,6 +539,8 @@ static int am33xx_pm_probe(struct platform_device *pdev)
|
||||
|
||||
static int am33xx_pm_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (pm_ops->deinit)
|
||||
pm_ops->deinit();
|
||||
suspend_set_ops(NULL);
|
||||
wkup_m3_ipc_put(m3_ipc);
|
||||
am33xx_pm_free_sram();
|
||||
|
@ -228,6 +228,8 @@
|
||||
#define TEGRA114_CLK_CLK_M 201
|
||||
#define TEGRA114_CLK_CLK_M_DIV2 202
|
||||
#define TEGRA114_CLK_CLK_M_DIV4 203
|
||||
#define TEGRA114_CLK_OSC_DIV2 202
|
||||
#define TEGRA114_CLK_OSC_DIV4 203
|
||||
#define TEGRA114_CLK_PLL_REF 204
|
||||
#define TEGRA114_CLK_PLL_C 205
|
||||
#define TEGRA114_CLK_PLL_C_OUT1 206
|
||||
@ -274,7 +276,7 @@
|
||||
#define TEGRA114_CLK_CLK_OUT_2 246
|
||||
#define TEGRA114_CLK_CLK_OUT_3 247
|
||||
#define TEGRA114_CLK_BLINK 248
|
||||
/* 249 */
|
||||
#define TEGRA114_CLK_OSC 249
|
||||
/* 250 */
|
||||
/* 251 */
|
||||
#define TEGRA114_CLK_XUSB_HOST_SRC 252
|
||||
|
@ -227,6 +227,8 @@
|
||||
#define TEGRA124_CLK_CLK_M 201
|
||||
#define TEGRA124_CLK_CLK_M_DIV2 202
|
||||
#define TEGRA124_CLK_CLK_M_DIV4 203
|
||||
#define TEGRA124_CLK_OSC_DIV2 202
|
||||
#define TEGRA124_CLK_OSC_DIV4 203
|
||||
#define TEGRA124_CLK_PLL_REF 204
|
||||
#define TEGRA124_CLK_PLL_C 205
|
||||
#define TEGRA124_CLK_PLL_C_OUT1 206
|
||||
@ -273,7 +275,7 @@
|
||||
#define TEGRA124_CLK_CLK_OUT_2 246
|
||||
#define TEGRA124_CLK_CLK_OUT_3 247
|
||||
#define TEGRA124_CLK_BLINK 248
|
||||
/* 249 */
|
||||
#define TEGRA124_CLK_OSC 249
|
||||
/* 250 */
|
||||
/* 251 */
|
||||
#define TEGRA124_CLK_XUSB_HOST_SRC 252
|
||||
|
@ -262,6 +262,8 @@
|
||||
#define TEGRA210_CLK_CLK_M 233
|
||||
#define TEGRA210_CLK_CLK_M_DIV2 234
|
||||
#define TEGRA210_CLK_CLK_M_DIV4 235
|
||||
#define TEGRA210_CLK_OSC_DIV2 234
|
||||
#define TEGRA210_CLK_OSC_DIV4 235
|
||||
#define TEGRA210_CLK_PLL_REF 236
|
||||
#define TEGRA210_CLK_PLL_C 237
|
||||
#define TEGRA210_CLK_PLL_C_OUT1 238
|
||||
@ -355,7 +357,7 @@
|
||||
#define TEGRA210_CLK_PLL_A_OUT_ADSP 323
|
||||
#define TEGRA210_CLK_PLL_A_OUT0_OUT_ADSP 324
|
||||
/* 325 */
|
||||
/* 326 */
|
||||
#define TEGRA210_CLK_OSC 326
|
||||
/* 327 */
|
||||
/* 328 */
|
||||
/* 329 */
|
||||
|
@ -196,6 +196,8 @@
|
||||
#define TEGRA30_CLK_CLK_M 171
|
||||
#define TEGRA30_CLK_CLK_M_DIV2 172
|
||||
#define TEGRA30_CLK_CLK_M_DIV4 173
|
||||
#define TEGRA30_CLK_OSC_DIV2 172
|
||||
#define TEGRA30_CLK_OSC_DIV4 173
|
||||
#define TEGRA30_CLK_PLL_REF 174
|
||||
#define TEGRA30_CLK_PLL_C 175
|
||||
#define TEGRA30_CLK_PLL_C_OUT1 176
|
||||
@ -243,7 +245,7 @@
|
||||
#define TEGRA30_CLK_HCLK 217
|
||||
#define TEGRA30_CLK_PCLK 218
|
||||
/* 219 */
|
||||
/* 220 */
|
||||
#define TEGRA30_CLK_OSC 220
|
||||
/* 221 */
|
||||
/* 222 */
|
||||
/* 223 */
|
||||
|
16
include/dt-bindings/soc/tegra-pmc.h
Normal file
16
include/dt-bindings/soc/tegra-pmc.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_SOC_TEGRA_PMC_H
|
||||
#define _DT_BINDINGS_SOC_TEGRA_PMC_H
|
||||
|
||||
#define TEGRA_PMC_CLK_OUT_1 0
|
||||
#define TEGRA_PMC_CLK_OUT_2 1
|
||||
#define TEGRA_PMC_CLK_OUT_3 2
|
||||
#define TEGRA_PMC_CLK_BLINK 3
|
||||
|
||||
#define TEGRA_PMC_CLK_MAX 4
|
||||
|
||||
#endif /* _DT_BINDINGS_SOC_TEGRA_PMC_H */
|
@ -12,6 +12,9 @@
|
||||
#ifndef AT91_PMC_H
|
||||
#define AT91_PMC_H
|
||||
|
||||
#define AT91_PMC_V1 (1) /* PMC version 1 */
|
||||
#define AT91_PMC_V2 (2) /* PMC version 2 [SAM9X60] */
|
||||
|
||||
#define AT91_PMC_SCER 0x00 /* System Clock Enable Register */
|
||||
#define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */
|
||||
|
||||
@ -30,16 +33,34 @@
|
||||
#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */
|
||||
#define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */
|
||||
|
||||
#define AT91_PMC_PLL_CTRL0 0x0C /* PLL Control Register 0 [for SAM9X60] */
|
||||
#define AT91_PMC_PLL_CTRL0_ENPLL (1 << 28) /* Enable PLL */
|
||||
#define AT91_PMC_PLL_CTRL0_ENPLLCK (1 << 29) /* Enable PLL clock for PMC */
|
||||
#define AT91_PMC_PLL_CTRL0_ENLOCK (1 << 31) /* Enable PLL lock */
|
||||
|
||||
#define AT91_PMC_PLL_CTRL1 0x10 /* PLL Control Register 1 [for SAM9X60] */
|
||||
|
||||
#define AT91_PMC_PCER 0x10 /* Peripheral Clock Enable Register */
|
||||
#define AT91_PMC_PCDR 0x14 /* Peripheral Clock Disable Register */
|
||||
#define AT91_PMC_PCSR 0x18 /* Peripheral Clock Status Register */
|
||||
|
||||
#define AT91_PMC_PLL_ACR 0x18 /* PLL Analog Control Register [for SAM9X60] */
|
||||
#define AT91_PMC_PLL_ACR_DEFAULT_UPLL 0x12020010UL /* Default PLL ACR value for UPLL */
|
||||
#define AT91_PMC_PLL_ACR_DEFAULT_PLLA 0x00020010UL /* Default PLL ACR value for PLLA */
|
||||
#define AT91_PMC_PLL_ACR_UTMIVR (1 << 12) /* UPLL Voltage regulator Control */
|
||||
#define AT91_PMC_PLL_ACR_UTMIBG (1 << 13) /* UPLL Bandgap Control */
|
||||
|
||||
#define AT91_CKGR_UCKR 0x1C /* UTMI Clock Register [some SAM9] */
|
||||
#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */
|
||||
#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */
|
||||
#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */
|
||||
#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */
|
||||
|
||||
#define AT91_PMC_PLL_UPDT 0x1C /* PMC PLL update register [for SAM9X60] */
|
||||
#define AT91_PMC_PLL_UPDT_UPDATE (1 << 8) /* Update PLL settings */
|
||||
#define AT91_PMC_PLL_UPDT_ID (1 << 0) /* PLL ID */
|
||||
#define AT91_PMC_PLL_UPDT_STUPTIM (0xff << 16) /* Startup time */
|
||||
|
||||
#define AT91_CKGR_MOR 0x20 /* Main Oscillator Register [not on SAM9RL] */
|
||||
#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */
|
||||
#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */
|
||||
@ -180,6 +201,8 @@
|
||||
#define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */
|
||||
#define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */
|
||||
|
||||
#define AT91_PMC_PLL_ISR0 0xEC /* PLL Interrupt Status Register 0 [SAM9X60 only] */
|
||||
|
||||
#define AT91_PMC_PCER1 0x100 /* Peripheral Clock Enable Register 1 [SAMA5 only]*/
|
||||
#define AT91_PMC_PCDR1 0x104 /* Peripheral Clock Enable Register 1 */
|
||||
#define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */
|
||||
|
@ -329,7 +329,7 @@ struct zynqmp_eemi_ops {
|
||||
int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
|
||||
u32 arg2, u32 arg3, u32 *ret_payload);
|
||||
|
||||
#if IS_REACHABLE(CONFIG_ARCH_ZYNQMP)
|
||||
#if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE)
|
||||
const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void);
|
||||
#else
|
||||
static inline struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void)
|
||||
|
@ -46,9 +46,13 @@ struct am33xx_pm_sram_addr {
|
||||
};
|
||||
|
||||
struct am33xx_pm_platform_data {
|
||||
int (*init)(void);
|
||||
int (*init)(int (*idle)(u32 wfi_flags));
|
||||
int (*deinit)(void);
|
||||
int (*soc_suspend)(unsigned int state, int (*fn)(unsigned long),
|
||||
unsigned long args);
|
||||
int (*cpu_suspend)(int (*fn)(unsigned long), unsigned long args);
|
||||
void (*begin_suspend)(void);
|
||||
void (*finish_suspend)(void);
|
||||
struct am33xx_pm_sram_addr *(*get_sram_addrs)(void);
|
||||
void __iomem *(*get_rtc_base_addr)(void);
|
||||
void (*save_context)(void);
|
||||
|
@ -6,7 +6,7 @@
|
||||
#ifndef __SOC_TEGRA_CPUIDLE_H__
|
||||
#define __SOC_TEGRA_CPUIDLE_H__
|
||||
|
||||
#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_TEGRA) && defined(CONFIG_CPU_IDLE)
|
||||
#ifdef CONFIG_ARM_TEGRA_CPUIDLE
|
||||
void tegra_cpuidle_pcie_irqs_in_use(void);
|
||||
#else
|
||||
static inline void tegra_cpuidle_pcie_irqs_in_use(void)
|
||||
|
@ -3,9 +3,11 @@
|
||||
* Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_IRQ_H
|
||||
#define __TEGRA_IRQ_H
|
||||
#ifndef __SOC_TEGRA_IRQ_H
|
||||
#define __SOC_TEGRA_IRQ_H
|
||||
|
||||
#if defined(CONFIG_ARM)
|
||||
bool tegra_pending_sgi(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __SOC_TEGRA_IRQ_H */
|
@ -6,6 +6,8 @@
|
||||
#ifndef __SOC_TEGRA_PM_H__
|
||||
#define __SOC_TEGRA_PM_H__
|
||||
|
||||
#include <linux/errno.h>
|
||||
|
||||
enum tegra_suspend_mode {
|
||||
TEGRA_SUSPEND_NONE = 0,
|
||||
TEGRA_SUSPEND_LP2, /* CPU voltage off */
|
||||
@ -20,6 +22,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
|
||||
|
||||
/* low-level resume entry point */
|
||||
void tegra_resume(void);
|
||||
|
||||
int tegra30_pm_secondary_cpu_suspend(unsigned long arg);
|
||||
void tegra_pm_clear_cpu_in_lp2(void);
|
||||
void tegra_pm_set_cpu_in_lp2(void);
|
||||
int tegra_pm_enter_lp2(void);
|
||||
int tegra_pm_park_secondary_cpu(unsigned long cpu);
|
||||
#else
|
||||
static inline enum tegra_suspend_mode
|
||||
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
|
||||
@ -30,6 +38,29 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
|
||||
static inline void tegra_resume(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int tegra30_pm_secondary_cpu_suspend(unsigned long arg)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline void tegra_pm_clear_cpu_in_lp2(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void tegra_pm_set_cpu_in_lp2(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int tegra_pm_enter_lp2(void)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int tegra_pm_park_secondary_cpu(unsigned long cpu)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
#endif /* __SOC_TEGRA_PM_H__ */
|
||||
|
@ -113,8 +113,9 @@ enum tegra_io_pad {
|
||||
TEGRA_IO_PAD_PEX_CLK_BIAS,
|
||||
TEGRA_IO_PAD_PEX_CLK1,
|
||||
TEGRA_IO_PAD_PEX_CLK2,
|
||||
TEGRA_IO_PAD_PEX_CLK2_BIAS,
|
||||
TEGRA_IO_PAD_PEX_CLK3,
|
||||
TEGRA_IO_PAD_PEX_CLK_2_BIAS,
|
||||
TEGRA_IO_PAD_PEX_CLK_2,
|
||||
TEGRA_IO_PAD_PEX_CNTRL,
|
||||
TEGRA_IO_PAD_PEX_CTL2,
|
||||
TEGRA_IO_PAD_PEX_L0_RST_N,
|
||||
|
Loading…
Reference in New Issue
Block a user