Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8aa15d82
Commit
8aa15d82
authored
Apr 04, 2013
by
Stephen Warren
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-3.10/soc' into for-3.10/clk
parents
8bb96604
4d82d058
Changes
43
Hide whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
1045 additions
and
405 deletions
+1045
-405
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
...tion/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
+66
-1
arch/arm/Kconfig
arch/arm/Kconfig
+1
-0
arch/arm/boot/dts/tegra114-dalmore.dts
arch/arm/boot/dts/tegra114-dalmore.dts
+13
-0
arch/arm/boot/dts/tegra114-pluto.dts
arch/arm/boot/dts/tegra114-pluto.dts
+13
-0
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra114.dtsi
+3
-1
arch/arm/boot/dts/tegra20-colibri-512.dtsi
arch/arm/boot/dts/tegra20-colibri-512.dtsi
+14
-1
arch/arm/boot/dts/tegra20-harmony.dts
arch/arm/boot/dts/tegra20-harmony.dts
+15
-2
arch/arm/boot/dts/tegra20-paz00.dts
arch/arm/boot/dts/tegra20-paz00.dts
+14
-1
arch/arm/boot/dts/tegra20-seaboard.dts
arch/arm/boot/dts/tegra20-seaboard.dts
+14
-1
arch/arm/boot/dts/tegra20-tamonten.dtsi
arch/arm/boot/dts/tegra20-tamonten.dtsi
+14
-1
arch/arm/boot/dts/tegra20-trimslice.dts
arch/arm/boot/dts/tegra20-trimslice.dts
+14
-1
arch/arm/boot/dts/tegra20-ventana.dts
arch/arm/boot/dts/tegra20-ventana.dts
+14
-1
arch/arm/boot/dts/tegra20-whistler.dts
arch/arm/boot/dts/tegra20-whistler.dts
+14
-0
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra20.dtsi
+4
-0
arch/arm/boot/dts/tegra30-beaver.dts
arch/arm/boot/dts/tegra30-beaver.dts
+14
-1
arch/arm/boot/dts/tegra30-cardhu.dtsi
arch/arm/boot/dts/tegra30-cardhu.dtsi
+14
-1
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/tegra30.dtsi
+5
-1
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/Makefile
+2
-3
arch/arm/mach-tegra/board-dt-tegra114.c
arch/arm/mach-tegra/board-dt-tegra114.c
+0
-46
arch/arm/mach-tegra/board-dt-tegra30.c
arch/arm/mach-tegra/board-dt-tegra30.c
+0
-60
arch/arm/mach-tegra/board-harmony-pcie.c
arch/arm/mach-tegra/board-harmony-pcie.c
+6
-1
arch/arm/mach-tegra/board.h
arch/arm/mach-tegra/board.h
+1
-3
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/common.c
+6
-25
arch/arm/mach-tegra/cpuidle-tegra20.c
arch/arm/mach-tegra/cpuidle-tegra20.c
+1
-5
arch/arm/mach-tegra/cpuidle-tegra30.c
arch/arm/mach-tegra/cpuidle-tegra30.c
+1
-9
arch/arm/mach-tegra/fuse.c
arch/arm/mach-tegra/fuse.c
+4
-0
arch/arm/mach-tegra/fuse.h
arch/arm/mach-tegra/fuse.h
+7
-0
arch/arm/mach-tegra/headsmp.S
arch/arm/mach-tegra/headsmp.S
+0
-3
arch/arm/mach-tegra/hotplug.c
arch/arm/mach-tegra/hotplug.c
+9
-14
arch/arm/mach-tegra/irq.c
arch/arm/mach-tegra/irq.c
+95
-1
arch/arm/mach-tegra/irq.h
arch/arm/mach-tegra/irq.h
+6
-0
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/platsmp.c
+54
-65
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.c
+82
-69
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/pm.h
+16
-1
arch/arm/mach-tegra/pmc.c
arch/arm/mach-tegra/pmc.c
+282
-28
arch/arm/mach-tegra/pmc.h
arch/arm/mach-tegra/pmc.h
+18
-0
arch/arm/mach-tegra/reset-handler.S
arch/arm/mach-tegra/reset-handler.S
+39
-9
arch/arm/mach-tegra/sleep.h
arch/arm/mach-tegra/sleep.h
+5
-5
arch/arm/mach-tegra/tegra.c
arch/arm/mach-tegra/tegra.c
+38
-7
arch/arm/mach-tegra/tegra114_speedo.c
arch/arm/mach-tegra/tegra114_speedo.c
+104
-0
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra20.c
+2
-34
drivers/clocksource/tegra20_timer.c
drivers/clocksource/tegra20_timer.c
+2
-2
drivers/gpio/gpio-tegra.c
drivers/gpio/gpio-tegra.c
+19
-2
No files found.
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
View file @
8aa15d82
NVIDIA Tegra Power Management Controller (PMC)
Properties:
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 "nvidia,tegra<chip>-pmc".
- reg : Offset and length of the register set for the device
- clocks : Must contain an entry for each entry in clock-names.
- 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.
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
{
...
clocks {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
clk32k_in: clock {
compatible = "fixed-clock";
reg=<0>;
#clock-cells = <0>;
clock-frequency = <32768>;
};
};
...
};
arch/arm/Kconfig
View file @
8aa15d82
...
...
@@ -673,6 +673,7 @@ config ARCH_TEGRA
select HAVE_CLK
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select SOC_BUS
select SPARSE_IRQ
select USE_OF
help
...
...
arch/arm/boot/dts/tegra114-dalmore.dts
View file @
8aa15d82
...
...
@@ -18,4 +18,17 @@ serial@70006300 {
pmc
{
nvidia
,
invert
-
interrupt
;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
};
arch/arm/boot/dts/tegra114-pluto.dts
View file @
8aa15d82
...
...
@@ -18,4 +18,17 @@ serial@70006300 {
pmc
{
nvidia
,
invert
-
interrupt
;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
};
arch/arm/boot/dts/tegra114.dtsi
View file @
8aa15d82
...
...
@@ -99,8 +99,10 @@ rtc {
};
pmc {
compatible = "nvidia,tegra114-pmc"
, "nvidia,tegra30-pmc"
;
compatible = "nvidia,tegra114-pmc";
reg = <0x7000e400 0x400>;
clocks = <&tegra_car 261>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
};
iommu {
...
...
arch/arm/boot/dts/tegra20-colibri-512.dtsi
View file @
8aa15d82
...
...
@@ -444,7 +444,20 @@ usb@c5004000 {
};
sdhci
@
c8000600
{
cd
-
gpios
=
<&
gpio
23
0
>;
/*
gpio
PC7
*/
cd
-
gpios
=
<&
gpio
23
1
>;
/*
gpio
PC7
*/
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
sound
{
...
...
arch/arm/boot/dts/tegra20-harmony.dts
View file @
8aa15d82
...
...
@@ -437,7 +437,7 @@ usb-phy@c5004400 {
sdhci
@
c8000200
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
69
0
>;
/*
gpio
PI5
*/
cd
-
gpios
=
<&
gpio
69
1
>;
/*
gpio
PI5
*/
wp
-
gpios
=
<&
gpio
57
0
>;
/*
gpio
PH1
*/
power
-
gpios
=
<&
gpio
155
0
>;
/*
gpio
PT3
*/
bus
-
width
=
<
4
>;
...
...
@@ -445,12 +445,25 @@ sdhci@c8000200 {
sdhci
@
c8000600
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
58
0
>;
/*
gpio
PH2
*/
cd
-
gpios
=
<&
gpio
58
1
>;
/*
gpio
PH2
*/
wp
-
gpios
=
<&
gpio
59
0
>;
/*
gpio
PH3
*/
power
-
gpios
=
<&
gpio
70
0
>;
/*
gpio
PI6
*/
bus
-
width
=
<
8
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
kbc
{
status
=
"okay"
;
nvidia
,
debounce
-
delay
-
ms
=
<
2
>;
...
...
arch/arm/boot/dts/tegra20-paz00.dts
View file @
8aa15d82
...
...
@@ -436,7 +436,7 @@ usb-phy@c5004400 {
sdhci
@
c8000000
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
173
0
>;
/*
gpio
PV5
*/
cd
-
gpios
=
<&
gpio
173
1
>;
/*
gpio
PV5
*/
wp
-
gpios
=
<&
gpio
57
0
>;
/*
gpio
PH1
*/
power
-
gpios
=
<&
gpio
169
0
>;
/*
gpio
PV1
*/
bus
-
width
=
<
4
>;
...
...
@@ -447,6 +447,19 @@ sdhci@c8000600 {
bus
-
width
=
<
8
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
gpio
-
keys
{
compatible
=
"gpio-keys"
;
...
...
arch/arm/boot/dts/tegra20-seaboard.dts
View file @
8aa15d82
...
...
@@ -584,7 +584,7 @@ sdhci@c8000000 {
sdhci
@
c8000400
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
69
0
>;
/*
gpio
PI5
*/
cd
-
gpios
=
<&
gpio
69
1
>;
/*
gpio
PI5
*/
wp
-
gpios
=
<&
gpio
57
0
>;
/*
gpio
PH1
*/
power
-
gpios
=
<&
gpio
70
0
>;
/*
gpio
PI6
*/
bus
-
width
=
<
4
>;
...
...
@@ -595,6 +595,19 @@ sdhci@c8000600 {
bus
-
width
=
<
8
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
gpio
-
keys
{
compatible
=
"gpio-keys"
;
...
...
arch/arm/boot/dts/tegra20-tamonten.dtsi
View file @
8aa15d82
...
...
@@ -465,12 +465,25 @@ usb@c5008000 {
};
sdhci
@
c8000600
{
cd
-
gpios
=
<&
gpio
58
0
>;
/*
gpio
PH2
*/
cd
-
gpios
=
<&
gpio
58
1
>;
/*
gpio
PH2
*/
wp
-
gpios
=
<&
gpio
59
0
>;
/*
gpio
PH3
*/
bus
-
width
=
<
4
>;
status
=
"okay"
;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
regulators
{
compatible
=
"simple-bus"
;
...
...
arch/arm/boot/dts/tegra20-trimslice.dts
View file @
8aa15d82
...
...
@@ -325,11 +325,24 @@ sdhci@c8000000 {
sdhci
@
c8000600
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
121
0
>;
/*
gpio
PP1
*/
cd
-
gpios
=
<&
gpio
121
1
>;
/*
gpio
PP1
*/
wp
-
gpios
=
<&
gpio
122
0
>;
/*
gpio
PP2
*/
bus
-
width
=
<
4
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
poweroff
{
compatible
=
"gpio-poweroff"
;
gpios
=
<&
gpio
191
1
>;
/*
gpio
PX7
,
active
low
*/
...
...
arch/arm/boot/dts/tegra20-ventana.dts
View file @
8aa15d82
...
...
@@ -520,7 +520,7 @@ sdhci@c8000000 {
sdhci
@
c8000400
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
69
0
>;
/*
gpio
PI5
*/
cd
-
gpios
=
<&
gpio
69
1
>;
/*
gpio
PI5
*/
wp
-
gpios
=
<&
gpio
57
0
>;
/*
gpio
PH1
*/
power
-
gpios
=
<&
gpio
70
0
>;
/*
gpio
PI6
*/
bus
-
width
=
<
4
>;
...
...
@@ -531,6 +531,19 @@ sdhci@c8000600 {
bus
-
width
=
<
8
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
regulators
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
...
...
arch/arm/boot/dts/tegra20-whistler.dts
View file @
8aa15d82
...
...
@@ -510,6 +510,7 @@ usb@c5008000 {
sdhci
@
c8000400
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
69
1
>;
/*
gpio
PI5
*/
wp
-
gpios
=
<&
gpio
173
0
>;
/*
gpio
PV5
*/
bus
-
width
=
<
8
>;
};
...
...
@@ -519,6 +520,19 @@ sdhci@c8000600 {
bus
-
width
=
<
8
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
kbc
{
status
=
"okay"
;
nvidia
,
debounce
-
delay
-
ms
=
<
20
>;
...
...
arch/arm/boot/dts/tegra20.dtsi
View file @
8aa15d82
...
...
@@ -145,6 +145,7 @@ timer@60005000 {
0 1 0x04
0 41 0x04
0 42 0x04>;
clocks = <&tegra_car 5>;
};
tegra_car: clock {
...
...
@@ -304,6 +305,7 @@ rtc {
compatible = "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <0 2 0x04>;
clocks = <&tegra_car 4>;
};
i2c@7000c000 {
...
...
@@ -416,6 +418,8 @@ kbc {
pmc {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
clocks = <&tegra_car 110>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
};
memory-controller@7000f000 {
...
...
arch/arm/boot/dts/tegra30-beaver.dts
View file @
8aa15d82
...
...
@@ -257,7 +257,7 @@ pmc {
sdhci
@
78000000
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
69
0
>;
/*
gpio
PI5
*/
cd
-
gpios
=
<&
gpio
69
1
>;
/*
gpio
PI5
*/
wp
-
gpios
=
<&
gpio
155
0
>;
/*
gpio
PT3
*/
power
-
gpios
=
<&
gpio
31
0
>;
/*
gpio
PD7
*/
bus
-
width
=
<
4
>;
...
...
@@ -268,6 +268,19 @@ sdhci@78000600 {
bus
-
width
=
<
8
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
regulators
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
...
...
arch/arm/boot/dts/tegra30-cardhu.dtsi
View file @
8aa15d82
...
...
@@ -311,7 +311,7 @@ pmc {
sdhci
@
78000000
{
status
=
"okay"
;
cd
-
gpios
=
<&
gpio
69
0
>;
/*
gpio
PI5
*/
cd
-
gpios
=
<&
gpio
69
1
>;
/*
gpio
PI5
*/
wp
-
gpios
=
<&
gpio
155
0
>;
/*
gpio
PT3
*/
power
-
gpios
=
<&
gpio
31
0
>;
/*
gpio
PD7
*/
bus
-
width
=
<
4
>;
...
...
@@ -322,6 +322,19 @@ sdhci@78000600 {
bus
-
width
=
<
8
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
clk32k_in
:
clock
{
compatible
=
"fixed-clock"
;
reg
=<
0
>;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
};
regulators
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
...
...
arch/arm/boot/dts/tegra30.dtsi
View file @
8aa15d82
...
...
@@ -148,6 +148,7 @@ timer@60005000 {
0 42 0x04
0 121 0x04
0 122 0x04>;
clocks = <&tegra_car 5>;
};
tegra_car: clock {
...
...
@@ -291,6 +292,7 @@ rtc {
compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
reg = <0x7000e000 0x100>;
interrupts = <0 2 0x04>;
clocks = <&tegra_car 4>;
};
i2c@7000c000 {
...
...
@@ -423,8 +425,10 @@ kbc {
};
pmc {
compatible = "nvidia,tegra
20-pmc", "nvidia,tegra
30-pmc";
compatible = "nvidia,tegra30-pmc";
reg = <0x7000e400 0x400>;
clocks = <&tegra_car 218>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
};
memory-controller {
...
...
arch/arm/mach-tegra/Makefile
View file @
8aa15d82
...
...
@@ -10,6 +10,7 @@ obj-y += pm.o
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)
+=
tegra20_speedo.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)
+=
tegra2_emc.o
...
...
@@ -27,9 +28,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_CPU_FREQ)
+=
cpu-tegra.o
obj-$(CONFIG_TEGRA_PCI)
+=
pcie.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)
+=
board-dt-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)
+=
board-dt-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC)
+=
board-dt-tegra114.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC)
+=
tegra114_speedo.o
ifeq
($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_ARCH_TEGRA_114_SOC)
+=
cpuidle-tegra114.o
endif
...
...
arch/arm/mach-tegra/board-dt-tegra114.c
deleted
100644 → 0
View file @
8bb96604
/*
* NVIDIA Tegra114 device tree board support
*
* Copyright (C) 2013 NVIDIA Corporation
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/clocksource.h>
#include <asm/mach/arch.h>
#include "board.h"
#include "common.h"
static
void
__init
tegra114_dt_init
(
void
)
{
of_platform_populate
(
NULL
,
of_default_bus_match_table
,
NULL
,
NULL
);
}
static
const
char
*
const
tegra114_dt_board_compat
[]
=
{
"nvidia,tegra114"
,
NULL
,
};
DT_MACHINE_START
(
TEGRA114_DT
,
"NVIDIA Tegra114 (Flattened Device Tree)"
)
.
smp
=
smp_ops
(
tegra_smp_ops
),
.
map_io
=
tegra_map_common_io
,
.
init_early
=
tegra114_init_early
,
.
init_irq
=
tegra_dt_init_irq
,
.
init_time
=
clocksource_of_init
,
.
init_machine
=
tegra114_dt_init
,
.
init_late
=
tegra_init_late
,
.
restart
=
tegra_assert_system_reset
,
.
dt_compat
=
tegra114_dt_board_compat
,
MACHINE_END
arch/arm/mach-tegra/board-dt-tegra30.c
deleted
100644 → 0
View file @
8bb96604
/*
* arch/arm/mach-tegra/board-dt-tegra30.c
*
* NVIDIA Tegra30 device tree board support
*
* Copyright (C) 2011 NVIDIA Corporation
*
* Derived from:
*
* arch/arm/mach-tegra/board-dt-tegra20.c
*
* Copyright (C) 2010 Secret Lab Technologies, Ltd.
* Copyright (C) 2010 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/clocksource.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
#include "board.h"
#include "common.h"
#include "iomap.h"
static
void
__init
tegra30_dt_init
(
void
)
{
of_platform_populate
(
NULL
,
of_default_bus_match_table
,
NULL
,
NULL
);
}
static
const
char
*
tegra30_dt_board_compat
[]
=
{
"nvidia,tegra30"
,
NULL
};
DT_MACHINE_START
(
TEGRA30_DT
,
"NVIDIA Tegra30 (Flattened Device Tree)"
)
.
smp
=
smp_ops
(
tegra_smp_ops
),
.
map_io
=
tegra_map_common_io
,
.
init_early
=
tegra30_init_early
,
.
init_irq
=
tegra_dt_init_irq
,
.
init_time
=
clocksource_of_init
,
.
init_machine
=
tegra30_dt_init
,
.
init_late
=
tegra_init_late
,
.
restart
=
tegra_assert_system_reset
,
.
dt_compat
=
tegra30_dt_board_compat
,
MACHINE_END
arch/arm/mach-tegra/board-harmony-pcie.c
View file @
8aa15d82
...
...
@@ -62,7 +62,11 @@ int __init harmony_pcie_init(void)
goto
err_reg
;
}
regulator_enable
(
regulator
);
err
=
regulator_enable
(
regulator
);
if
(
err
)
{
pr_err
(
"%s: regulator_enable failed: %d
\n
"
,
__func__
,
err
);
goto
err_en
;
}
err
=
tegra_pcie_init
(
true
,
true
);
if
(
err
)
{
...
...
@@ -74,6 +78,7 @@ int __init harmony_pcie_init(void)
err_pcie:
regulator_disable
(
regulator
);
err_en:
regulator_put
(
regulator
);
err_reg:
gpio_free
(
en_vdd_1v05
);
...
...
arch/arm/mach-tegra/board.h
View file @
8aa15d82
...
...
@@ -26,9 +26,7 @@
void
tegra_assert_system_reset
(
char
mode
,
const
char
*
cmd
);
void
__init
tegra20_init_early
(
void
);
void
__init
tegra30_init_early
(
void
);
void
__init
tegra114_init_early
(
void
);
void
__init
tegra_init_early
(
void
);
void
__init
tegra_map_common_io
(
void
);
void
__init
tegra_init_irq
(
void
);
void
__init
tegra_dt_init_irq
(
void
);
...
...
arch/arm/mach-tegra/common.c
View file @
8aa15d82
...
...
@@ -33,6 +33,7 @@
#include "common.h"
#include "fuse.h"
#include "iomap.h"
#include "irq.h"
#include "pmc.h"
#include "apbio.h"
#include "sleep.h"
...
...
@@ -61,8 +62,10 @@ u32 tegra_uart_config[4] = {
void
__init
tegra_dt_init_irq
(
void
)
{
tegra_clocks_init
();
tegra_pmc_init
();
tegra_init_irq
();
irqchip_init
();
tegra_legacy_irq_syscore_init
();
}
#endif
...
...
@@ -94,40 +97,18 @@ static void __init tegra_init_cache(void)
}
static
void
__init
tegra_init_early
(
void
)
void
__init
tegra_init_early
(
void
)
{
tegra_cpu_reset_handler_init
();
tegra_apb_io_init
();
tegra_init_fuse
();
tegra_init_cache
();
tegra_pmc_init
();
tegra_powergate_init
();
tegra_hotplug_init
();
}
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
void
__init
tegra20_init_early
(
void
)
{
tegra_init_early
();
tegra20_hotplug_init
();
}
#endif
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
void
__init
tegra30_init_early
(
void
)
{
tegra_init_early
();
tegra30_hotplug_init
();
}
#endif
#ifdef CONFIG_ARCH_TEGRA_114_SOC
void
__init
tegra114_init_early
(
void
)
{
tegra_init_early
();
}
#endif
void
__init
tegra_init_late
(
void
)
{
tegra_init_suspend
();
tegra_powergate_debugfs_init
();
}
arch/arm/mach-tegra/cpuidle-tegra20.c
View file @
8aa15d82
...
...
@@ -130,10 +130,6 @@ static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
struct
cpuidle_driver
*
drv
,
int
index
)
{
struct
cpuidle_state
*
state
=
&
drv
->
states
[
index
];
u32
cpu_on_time
=
state
->
exit_latency
;
u32
cpu_off_time
=
state
->
target_residency
-
state
->
exit_latency
;
while
(
tegra20_cpu_is_resettable_soon
())
cpu_relax
();
...
...
@@ -142,7 +138,7 @@ static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
clockevents_notify
(
CLOCK_EVT_NOTIFY_BROADCAST_ENTER
,
&
dev
->
cpu
);
tegra_idle_lp2_last
(
cpu_on_time
,
cpu_off_time
);
tegra_idle_lp2_last
();
clockevents_notify
(
CLOCK_EVT_NOTIFY_BROADCAST_EXIT
,
&
dev
->
cpu
);
...
...
arch/arm/mach-tegra/cpuidle-tegra30.c
View file @
8aa15d82
...
...
@@ -72,10 +72,6 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
struct
cpuidle_driver
*
drv
,
int
index
)
{
struct
cpuidle_state
*
state
=
&
drv
->
states
[
index
];
u32
cpu_on_time
=
state
->
exit_latency
;
u32
cpu_off_time
=
state
->
target_residency
-
state
->
exit_latency
;
/* All CPUs entering LP2 is not working.
* Don't let CPU0 enter LP2 when any secondary CPU is online.
*/
...
...
@@ -86,7 +82,7 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
clockevents_notify
(
CLOCK_EVT_NOTIFY_BROADCAST_ENTER
,
&
dev
->
cpu
);
tegra_idle_lp2_last
(
cpu_on_time
,
cpu_off_time
);
tegra_idle_lp2_last
();
clockevents_notify
(
CLOCK_EVT_NOTIFY_BROADCAST_EXIT
,
&
dev
->
cpu
);
...
...
@@ -102,12 +98,8 @@ static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
smp_wmb
();
save_cpu_arch_register
();
cpu_suspend
(
0
,
tegra30_sleep_cpu_secondary_finish
);
restore_cpu_arch_register
();
clockevents_notify
(
CLOCK_EVT_NOTIFY_BROADCAST_EXIT
,
&
dev
->
cpu
);
return
true
;
...
...
arch/arm/mach-tegra/fuse.c
View file @
8aa15d82
...
...
@@ -2,6 +2,7 @@
* arch/arm/mach-tegra/fuse.c
*
* Copyright (C) 2010 Google, Inc.
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* Author:
* Colin Cross <ccross@android.com>
...
...
@@ -137,6 +138,9 @@ void tegra_init_fuse(void)
tegra_fuse_spare_bit
=
TEGRA30_FUSE_SPARE_BIT
;
tegra_init_speedo_data
=
&
tegra30_init_speedo_data
;
break
;
case
TEGRA114
:
tegra_init_speedo_data
=
&
tegra114_init_speedo_data
;
break
;
default:
pr_warn
(
"Tegra: unknown chip id %d
\n
"
,
tegra_chip_id
);
tegra_fuse_spare_bit
=
TEGRA20_FUSE_SPARE_BIT
;
...
...
arch/arm/mach-tegra/fuse.h
View file @
8aa15d82
/*
* Copyright (C) 2010 Google, Inc.
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* Author:
* Colin Cross <ccross@android.com>
...
...
@@ -66,4 +67,10 @@ void tegra30_init_speedo_data(void);
static
inline
void
tegra30_init_speedo_data
(
void
)
{}
#endif
#ifdef CONFIG_ARCH_TEGRA_114_SOC
void
tegra114_init_speedo_data
(
void
);
#else
static
inline
void
tegra114_init_speedo_data
(
void
)
{}
#endif
#endif
arch/arm/mach-tegra/headsmp.S
View file @
8aa15d82
...
...
@@ -7,8 +7,5 @@
ENTRY
(
tegra_secondary_startup
)
bl
v7_invalidate_l1
/
*
Enable
coresight
*/
mov32
r0
,
0xC5ACCE55
mcr
p14
,
0
,
r0
,
c7
,
c12
,
6
b
secondary_startup
ENDPROC
(
tegra_secondary_startup
)
arch/arm/mach-tegra/hotplug.c
View file @
8aa15d82
/*
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
* Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved.
* Copyright (c) 2010, 2012
-2013,
NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
...
...
@@ -15,6 +14,7 @@
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include "fuse.h"
#include "sleep.h"
static
void
(
*
tegra_hotplug_shutdown
)(
void
);
...
...
@@ -56,18 +56,13 @@ int tegra_cpu_disable(unsigned int cpu)
return
cpu
==
0
?
-
EPERM
:
0
;
}
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
extern
void
tegra20_hotplug_shutdown
(
void
);
void
__init
tegra20_hotplug_init
(
void
)
void
__init
tegra_hotplug_init
(
void
)
{
tegra_hotplug_shutdown
=
tegra20_hotplug_shutdown
;
}
#endif
if
(
!
IS_ENABLED
(
CONFIG_HOTPLUG_CPU
))
return
;
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
extern
void
tegra30_hotplug_shutdown
(
void
);
void
__init
tegra30_hotplug_init
(
void
)
{
tegra_hotplug_shutdown
=
tegra30_hotplug_shutdown
;
if
(
IS_ENABLED
(
CONFIG_ARCH_TEGRA_2x_SOC
)
&&
tegra_chip_id
==
TEGRA20
)
tegra_hotplug_shutdown
=
tegra20_hotplug_shutdown
;
if
(
IS_ENABLED
(
CONFIG_ARCH_TEGRA_3x_SOC
)
&&
tegra_chip_id
==
TEGRA30
)
tegra_hotplug_shutdown
=
tegra30_hotplug_shutdown
;
}
#endif
arch/arm/mach-tegra/irq.c
View file @
8aa15d82
...
...
@@ -4,7 +4,7 @@
* Author:
* Colin Cross <ccross@android.com>
*
* Copyright (C) 2010, NVIDIA Corporation
* Copyright (C) 2010,
2013,
NVIDIA Corporation
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
...
...
@@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/syscore_ops.h>
#include "board.h"
#include "iomap.h"
...
...
@@ -43,6 +44,7 @@
#define ICTLR_COP_IEP_CLASS 0x3c
#define FIRST_LEGACY_IRQ 32
#define TEGRA_MAX_NUM_ICTLRS 5
#define SGI_MASK 0xFFFF
...
...
@@ -56,6 +58,15 @@ static void __iomem *ictlr_reg_base[] = {
IO_ADDRESS
(
TEGRA_QUINARY_ICTLR_BASE
),
};
#ifdef CONFIG_PM_SLEEP
static
u32
cop_ier
[
TEGRA_MAX_NUM_ICTLRS
];
static
u32
cop_iep
[
TEGRA_MAX_NUM_ICTLRS
];
static
u32
cpu_ier
[
TEGRA_MAX_NUM_ICTLRS
];
static
u32
cpu_iep
[
TEGRA_MAX_NUM_ICTLRS
];
static
u32
ictlr_wake_mask
[
TEGRA_MAX_NUM_ICTLRS
];
#endif
bool
tegra_pending_sgi
(
void
)
{
u32
pending_set
;
...
...
@@ -125,6 +136,87 @@ static int tegra_retrigger(struct irq_data *d)
return
1
;
}
#ifdef CONFIG_PM_SLEEP
static
int
tegra_set_wake
(
struct
irq_data
*
d
,
unsigned
int
enable
)
{
u32
irq
=
d
->
irq
;
u32
index
,
mask
;
if
(
irq
<
FIRST_LEGACY_IRQ
||
irq
>=
FIRST_LEGACY_IRQ
+
num_ictlrs
*
32
)
return
-
EINVAL
;
index
=
((
irq
-
FIRST_LEGACY_IRQ
)
/
32
);
mask
=
BIT
((
irq
-
FIRST_LEGACY_IRQ
)
%
32
);
if
(
enable
)
ictlr_wake_mask
[
index
]
|=
mask
;
else
ictlr_wake_mask
[
index
]
&=
~
mask
;
return
0
;
}
static
int
tegra_legacy_irq_suspend
(
void
)
{
unsigned
long
flags
;
int
i
;
local_irq_save
(
flags
);
for
(
i
=
0
;
i
<
num_ictlrs
;
i
++
)
{
void
__iomem
*
ictlr
=
ictlr_reg_base
[
i
];
/* Save interrupt state */
cpu_ier
[
i
]
=
readl_relaxed
(
ictlr
+
ICTLR_CPU_IER
);
cpu_iep
[
i
]
=
readl_relaxed
(
ictlr
+
ICTLR_CPU_IEP_CLASS
);
cop_ier
[
i
]
=
readl_relaxed
(
ictlr
+
ICTLR_COP_IER
);
cop_iep
[
i
]
=
readl_relaxed
(
ictlr
+
ICTLR_COP_IEP_CLASS
);
/* Disable COP interrupts */
writel_relaxed
(
~
0ul
,
ictlr
+
ICTLR_COP_IER_CLR
);
/* Disable CPU interrupts */
writel_relaxed
(
~
0ul
,
ictlr
+
ICTLR_CPU_IER_CLR
);
/* Enable the wakeup sources of ictlr */
writel_relaxed
(
ictlr_wake_mask
[
i
],
ictlr
+
ICTLR_CPU_IER_SET
);
}
local_irq_restore
(
flags
);
return
0
;
}
static
void
tegra_legacy_irq_resume
(
void
)
{
unsigned
long
flags
;
int
i
;
local_irq_save
(
flags
);
for
(
i
=
0
;
i
<
num_ictlrs
;
i
++
)
{
void
__iomem
*
ictlr
=
ictlr_reg_base
[
i
];
writel_relaxed
(
cpu_iep
[
i
],
ictlr
+
ICTLR_CPU_IEP_CLASS
);
writel_relaxed
(
~
0ul
,
ictlr
+
ICTLR_CPU_IER_CLR
);
writel_relaxed
(
cpu_ier
[
i
],
ictlr
+
ICTLR_CPU_IER_SET
);
writel_relaxed
(
cop_iep
[
i
],
ictlr
+
ICTLR_COP_IEP_CLASS
);
writel_relaxed
(
~
0ul
,
ictlr
+
ICTLR_COP_IER_CLR
);
writel_relaxed
(
cop_ier
[
i
],
ictlr
+
ICTLR_COP_IER_SET
);
}
local_irq_restore
(
flags
);
}
static
struct
syscore_ops
tegra_legacy_irq_syscore_ops
=
{
.
suspend
=
tegra_legacy_irq_suspend
,
.
resume
=
tegra_legacy_irq_resume
,
};
int
tegra_legacy_irq_syscore_init
(
void
)
{
register_syscore_ops
(
&
tegra_legacy_irq_syscore_ops
);
return
0
;
}
#else
#define tegra_set_wake NULL
#endif
void
__init
tegra_init_irq
(
void
)
{
int
i
;
...
...
@@ -150,6 +242,8 @@ void __init tegra_init_irq(void)
gic_arch_extn
.
irq_mask
=
tegra_mask
;
gic_arch_extn
.
irq_unmask
=
tegra_unmask
;
gic_arch_extn
.
irq_retrigger
=
tegra_retrigger
;
gic_arch_extn
.
irq_set_wake
=
tegra_set_wake
;
gic_arch_extn
.
flags
=
IRQCHIP_MASK_ON_SUSPEND
;
/*
* Check if there is a devicetree present, since the GIC will be
...
...
arch/arm/mach-tegra/irq.h
View file @
8aa15d82
...
...
@@ -19,4 +19,10 @@
bool
tegra_pending_sgi
(
void
);
#ifdef CONFIG_PM_SLEEP
int
tegra_legacy_irq_syscore_init
(
void
);
#else
static
inline
int
tegra_legacy_irq_syscore_init
(
void
)
{
return
0
;
}
#endif
#endif
arch/arm/mach-tegra/platsmp.c
View file @
8aa15d82
...
...
@@ -26,22 +26,16 @@
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
#include <mach/powergate.h>
#include "fuse.h"
#include "flowctrl.h"
#include "reset.h"
#include "pmc.h"
#include "common.h"
#include "iomap.h"
extern
void
tegra_secondary_startup
(
void
);
static
cpumask_t
tegra_cpu_init_mask
;
#define EVP_CPU_RESET_VECTOR \
(IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
static
void
__cpuinit
tegra_secondary_init
(
unsigned
int
cpu
)
{
/*
...
...
@@ -54,25 +48,43 @@ static void __cpuinit tegra_secondary_init(unsigned int cpu)
cpumask_set_cpu
(
cpu
,
&
tegra_cpu_init_mask
);
}
static
int
tegra20_power_up_cpu
(
unsigned
int
cpu
)
static
int
tegra20_boot_secondary
(
unsigned
int
cpu
,
struct
task_struct
*
idle
)
{
/* Enable the CPU clock. */
tegra_enable_cpu_clock
(
cpu
);
cpu
=
cpu_logical_map
(
cpu
);
/*
* Force the CPU into reset. The CPU must remain in reset when
* the flow controller state is cleared (which will cause the
* flow controller to stop driving reset if the CPU has been
* power-gated via the flow controller). This will have no
* effect on first boot of the CPU since it should already be
* in reset.
*/
tegra_put_cpu_in_reset
(
cpu
);
/* Clear flow controller CSR. */
flowctrl_write_cpu_csr
(
cpu
,
0
);
/*
* Unhalt the CPU. If the flow controller was used to
* power-gate the CPU this will cause the flow controller to
* stop driving reset. The CPU will remain in reset because the
* clock and reset block is now driving reset.
*/
flowctrl_write_cpu_halt
(
cpu
,
0
);
tegra_enable_cpu_clock
(
cpu
);
flowctrl_write_cpu_csr
(
cpu
,
0
);
/* Clear flow controller CSR. */
tegra_cpu_out_of_reset
(
cpu
);
return
0
;
}
static
int
tegra30_
power_up_cpu
(
unsigned
int
cpu
)
static
int
tegra30_
boot_secondary
(
unsigned
int
cpu
,
struct
task_struct
*
idle
)
{
int
ret
,
pwrgateid
;
int
ret
;
unsigned
long
timeout
;
pwrgateid
=
tegra_cpu_powergate_id
(
cpu
);
if
(
pwrgateid
<
0
)
return
pwrgateid
;
cpu
=
cpu_logical_map
(
cpu
);
tegra_put_cpu_in_reset
(
cpu
);
flowctrl_write_cpu_halt
(
cpu
,
0
)
;
/*
* The power up sequence of cold boot CPU and warm boot CPU
...
...
@@ -85,13 +97,13 @@ static int tegra30_power_up_cpu(unsigned int cpu)
* the IO clamps.
* For cold boot CPU, do not wait. After the cold boot CPU be
* booted, it will run to tegra_secondary_init() and set
* tegra_cpu_init_mask which influences what tegra30_
power_up_cpu
()
* tegra_cpu_init_mask which influences what tegra30_
boot_secondary
()
* next time around.
*/
if
(
cpumask_test_cpu
(
cpu
,
&
tegra_cpu_init_mask
))
{
timeout
=
jiffies
+
msecs_to_jiffies
(
50
);
do
{
if
(
!
tegra_powergate_is_powered
(
pwrgateid
))
if
(
tegra_pmc_cpu_is_powered
(
cpu
))
goto
remove_clamps
;
udelay
(
10
);
}
while
(
time_before
(
jiffies
,
timeout
));
...
...
@@ -103,14 +115,14 @@ static int tegra30_power_up_cpu(unsigned int cpu)
* be un-gated by un-toggling the power gate register
* manually.
*/
if
(
!
tegra_p
owergate_is_powered
(
pwrgateid
))
{
ret
=
tegra_p
owergate_power_on
(
pwrgateid
);
if
(
!
tegra_p
mc_cpu_is_powered
(
cpu
))
{
ret
=
tegra_p
mc_cpu_power_on
(
cpu
);
if
(
ret
)
return
ret
;
/* Wait for the power to come up. */
timeout
=
jiffies
+
msecs_to_jiffies
(
100
);
while
(
tegra_p
owergate_is_powered
(
pwrgateid
))
{
while
(
tegra_p
mc_cpu_is_powered
(
cpu
))
{
if
(
time_after
(
jiffies
,
timeout
))
return
-
ETIMEDOUT
;
udelay
(
10
);
...
...
@@ -123,57 +135,34 @@ static int tegra30_power_up_cpu(unsigned int cpu)
udelay
(
10
);
/* Remove I/O clamps. */
ret
=
tegra_powergate_remove_clamping
(
pwrgateid
);
udelay
(
10
);
ret
=
tegra_pmc_cpu_remove_clamping
(
cpu
);
if
(
ret
)
return
ret
;
/* Clear flow controller CSR. */
flowctrl_write_cpu_csr
(
cpu
,
0
);
udelay
(
10
);
flowctrl_write_cpu_csr
(
cpu
,
0
);
/* Clear flow controller CSR. */
tegra_cpu_out_of_reset
(
cpu
);
return
0
;
}
static
int
__cpuinit
tegra
_boot_secondary
(
unsigned
int
cpu
,
struct
task_struct
*
idle
)
static
int
tegra114
_boot_secondary
(
unsigned
int
cpu
,
struct
task_struct
*
idle
)
{
int
status
;
cpu
=
cpu_logical_map
(
cpu
);
return
tegra_pmc_cpu_power_on
(
cpu
);
}
/*
* Force the CPU into reset. The CPU must remain in reset when the
* flow controller state is cleared (which will cause the flow
* controller to stop driving reset if the CPU has been power-gated
* via the flow controller). This will have no effect on first boot
* of the CPU since it should already be in reset.
*/
tegra_put_cpu_in_reset
(
cpu
);
/*
* Unhalt the CPU. If the flow controller was used to power-gate the
* CPU this will cause the flow controller to stop driving reset.
* The CPU will remain in reset because the clock and reset block
* is now driving reset.
*/
flowctrl_write_cpu_halt
(
cpu
,
0
);
switch
(
tegra_chip_id
)
{
case
TEGRA20
:
status
=
tegra20_power_up_cpu
(
cpu
);
break
;
case
TEGRA30
:
status
=
tegra30_power_up_cpu
(
cpu
);
break
;
default:
status
=
-
EINVAL
;
break
;
}
if
(
status
)
goto
done
;
/* Take the CPU out of reset. */
tegra_cpu_out_of_reset
(
cpu
);
done:
return
status
;
static
int
__cpuinit
tegra_boot_secondary
(
unsigned
int
cpu
,
struct
task_struct
*
idle
)
{
if
(
IS_ENABLED
(
CONFIG_ARCH_TEGRA_2x_SOC
)
&&
tegra_chip_id
==
TEGRA20
)
return
tegra20_boot_secondary
(
cpu
,
idle
);
if
(
IS_ENABLED
(
CONFIG_ARCH_TEGRA_3x_SOC
)
&&
tegra_chip_id
==
TEGRA30
)
return
tegra30_boot_secondary
(
cpu
,
idle
);
if
(
IS_ENABLED
(
CONFIG_ARCH_TEGRA_114_SOC
)
&&
tegra_chip_id
==
TEGRA114
)
return
tegra114_boot_secondary
(
cpu
,
idle
);
return
-
EINVAL
;
}
static
void
__init
tegra_smp_prepare_cpus
(
unsigned
int
max_cpus
)
...
...
arch/arm/mach-tegra/pm.c
View file @
8aa15d82
...
...
@@ -22,7 +22,7 @@
#include <linux/cpumask.h>
#include <linux/delay.h>
#include <linux/cpu_pm.h>
#include <linux/
clk
.h>
#include <linux/
suspend
.h>
#include <linux/err.h>
#include <linux/clk/tegra.h>
...
...
@@ -37,67 +37,14 @@
#include "reset.h"
#include "flowctrl.h"
#include "fuse.h"
#include "pmc.h"
#include "sleep.h"
#define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16)
/* CPU pwr req enable */
#define PMC_CTRL 0x0
#define PMC_CPUPWRGOOD_TIMER 0xc8
#define PMC_CPUPWROFF_TIMER 0xcc
#include "pmc.h"
#ifdef CONFIG_PM_SLEEP
static
unsigned
int
g_diag_reg
;
static
DEFINE_SPINLOCK
(
tegra_lp2_lock
);
static
void
__iomem
*
pmc
=
IO_ADDRESS
(
TEGRA_PMC_BASE
);
static
struct
clk
*
tegra_pclk
;
void
(
*
tegra_tear_down_cpu
)(
void
);
void
save_cpu_arch_register
(
void
)
{
/* read diagnostic register */
asm
(
"mrc p15, 0, %0, c15, c0, 1"
:
"=r"
(
g_diag_reg
)
:
:
"cc"
);
return
;
}
void
restore_cpu_arch_register
(
void
)
{
/* write diagnostic register */
asm
(
"mcr p15, 0, %0, c15, c0, 1"
:
:
"r"
(
g_diag_reg
)
:
"cc"
);
return
;
}
static
void
set_power_timers
(
unsigned
long
us_on
,
unsigned
long
us_off
)
{
unsigned
long
long
ticks
;
unsigned
long
long
pclk
;
unsigned
long
rate
;
static
unsigned
long
tegra_last_pclk
;
if
(
tegra_pclk
==
NULL
)
{
tegra_pclk
=
clk_get_sys
(
NULL
,
"pclk"
);
WARN_ON
(
IS_ERR
(
tegra_pclk
));
}
rate
=
clk_get_rate
(
tegra_pclk
);
if
(
WARN_ON_ONCE
(
rate
<=
0
))
pclk
=
100000000
;
else
pclk
=
rate
;
if
((
rate
!=
tegra_last_pclk
))
{
ticks
=
(
us_on
*
pclk
)
+
999999ull
;
do_div
(
ticks
,
1000000
);
writel
((
unsigned
long
)
ticks
,
pmc
+
PMC_CPUPWRGOOD_TIMER
);
ticks
=
(
us_off
*
pclk
)
+
999999ull
;
do_div
(
ticks
,
1000000
);
writel
((
unsigned
long
)
ticks
,
pmc
+
PMC_CPUPWROFF_TIMER
);
wmb
();
}
tegra_last_pclk
=
pclk
;
}
/*
* restore_cpu_complex
*
...
...
@@ -119,8 +66,6 @@ static void restore_cpu_complex(void)
tegra_cpu_clock_resume
();
flowctrl_cpu_suspend_exit
(
cpu
);
restore_cpu_arch_register
();
}
/*
...
...
@@ -145,8 +90,6 @@ static void suspend_cpu_complex(void)
tegra_cpu_clock_suspend
();
flowctrl_cpu_suspend_enter
(
cpu
);
save_cpu_arch_register
();
}
void
tegra_clear_cpu_in_lp2
(
int
phy_cpu_id
)
...
...
@@ -197,16 +140,9 @@ static int tegra_sleep_cpu(unsigned long v2p)
return
0
;
}
void
tegra_idle_lp2_last
(
u32
cpu_on_time
,
u32
cpu_off_time
)
void
tegra_idle_lp2_last
(
void
)
{
u32
mode
;
/* Only the last cpu down does the final suspend steps */
mode
=
readl
(
pmc
+
PMC_CTRL
);
mode
|=
TEGRA_POWER_CPU_PWRREQ_OE
;
writel
(
mode
,
pmc
+
PMC_CTRL
);
set_power_timers
(
cpu_on_time
,
cpu_off_time
);
tegra_pmc_pm_set
(
TEGRA_SUSPEND_LP2
);
cpu_cluster_pm_enter
();
suspend_cpu_complex
();
...
...
@@ -216,4 +152,81 @@ void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time)
restore_cpu_complex
();
cpu_cluster_pm_exit
();
}
enum
tegra_suspend_mode
tegra_pm_validate_suspend_mode
(
enum
tegra_suspend_mode
mode
)
{
/* Tegra114 didn't support any suspending mode yet. */
if
(
tegra_chip_id
==
TEGRA114
)
return
TEGRA_SUSPEND_NONE
;
/*
* The Tegra devices only support suspending to LP2 currently.
*/
if
(
mode
>
TEGRA_SUSPEND_LP2
)
return
TEGRA_SUSPEND_LP2
;
return
mode
;
}
static
const
char
*
lp_state
[
TEGRA_MAX_SUSPEND_MODE
]
=
{
[
TEGRA_SUSPEND_NONE
]
=
"none"
,
[
TEGRA_SUSPEND_LP2
]
=
"LP2"
,
[
TEGRA_SUSPEND_LP1
]
=
"LP1"
,
[
TEGRA_SUSPEND_LP0
]
=
"LP0"
,
};
static
int
__cpuinit
tegra_suspend_enter
(
suspend_state_t
state
)
{
enum
tegra_suspend_mode
mode
=
tegra_pmc_get_suspend_mode
();
if
(
WARN_ON
(
mode
<
TEGRA_SUSPEND_NONE
||
mode
>=
TEGRA_MAX_SUSPEND_MODE
))
return
-
EINVAL
;
pr_info
(
"Entering suspend state %s
\n
"
,
lp_state
[
mode
]);
tegra_pmc_pm_set
(
mode
);
local_fiq_disable
();
suspend_cpu_complex
();
switch
(
mode
)
{
case
TEGRA_SUSPEND_LP2
:
tegra_set_cpu_in_lp2
(
0
);
break
;
default:
break
;
}
cpu_suspend
(
PHYS_OFFSET
-
PAGE_OFFSET
,
&
tegra_sleep_cpu
);
switch
(
mode
)
{
case
TEGRA_SUSPEND_LP2
:
tegra_clear_cpu_in_lp2
(
0
);
break
;
default:
break
;
}
restore_cpu_complex
();
local_fiq_enable
();
return
0
;
}
static
const
struct
platform_suspend_ops
tegra_suspend_ops
=
{
.
valid
=
suspend_valid_only_mem
,
.
enter
=
tegra_suspend_enter
,
};
void
__init
tegra_init_suspend
(
void
)
{
if
(
tegra_pmc_get_suspend_mode
()
==
TEGRA_SUSPEND_NONE
)
return
;
tegra_pmc_suspend_init
();
suspend_set_ops
(
&
tegra_suspend_ops
);
}
#endif
arch/arm/mach-tegra/pm.h
View file @
8aa15d82
...
...
@@ -21,6 +21,8 @@
#ifndef _MACH_TEGRA_PM_H_
#define _MACH_TEGRA_PM_H_
#include "pmc.h"
extern
unsigned
long
l2x0_saved_regs_addr
;
void
save_cpu_arch_register
(
void
);
...
...
@@ -29,7 +31,20 @@ void restore_cpu_arch_register(void);
void
tegra_clear_cpu_in_lp2
(
int
phy_cpu_id
);
bool
tegra_set_cpu_in_lp2
(
int
phy_cpu_id
);
void
tegra_idle_lp2_last
(
u32
cpu_on_time
,
u32
cpu_off_time
);
void
tegra_idle_lp2_last
(
void
);
extern
void
(
*
tegra_tear_down_cpu
)(
void
);
#ifdef CONFIG_PM_SLEEP
enum
tegra_suspend_mode
tegra_pm_validate_suspend_mode
(
enum
tegra_suspend_mode
mode
);
void
tegra_init_suspend
(
void
);
#else
enum
tegra_suspend_mode
tegra_pm_validate_suspend_mode
(
enum
tegra_suspend_mode
mode
)
{
return
TEGRA_SUSPEND_NONE
;
}
static
inline
void
tegra_init_suspend
(
void
)
{}
#endif
#endif
/* _MACH_TEGRA_PM_H_ */
arch/arm/mach-tegra/pmc.c
View file @
8aa15d82
/*
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
* Copyright (C) 2012
,2013
NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
...
...
@@ -16,59 +16,313 @@
*/
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include "iomap.h"
#include "fuse.h"
#include "pm.h"
#include "pmc.h"
#include "sleep.h"
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
#define TEGRA_POWER_EFFECT_LP0 (1 << 14)
/* LP0 when CPU pwr gated */
#define TEGRA_POWER_CPU_PWRREQ_POLARITY (1 << 15)
/* CPU pwr req polarity */
#define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16)
/* CPU pwr req enable */
#define PMC_CTRL 0x0
#define PMC_CTRL_INTR_LOW (1 << 17)
#define PMC_PWRGATE_TOGGLE 0x30
#define PMC_PWRGATE_TOGGLE_START (1 << 8)
#define PMC_REMOVE_CLAMPING 0x34
#define PMC_PWRGATE_STATUS 0x38
#define PMC_CPUPWRGOOD_TIMER 0xc8
#define PMC_CPUPWROFF_TIMER 0xcc
#define TEGRA_POWERGATE_PCIE 3
#define TEGRA_POWERGATE_VDEC 4
#define TEGRA_POWERGATE_CPU1 9
#define TEGRA_POWERGATE_CPU2 10
#define TEGRA_POWERGATE_CPU3 11
static
u8
tegra_cpu_domains
[]
=
{
0xFF
,
/* not available for CPU0 */
TEGRA_POWERGATE_CPU1
,
TEGRA_POWERGATE_CPU2
,
TEGRA_POWERGATE_CPU3
,
};
static
DEFINE_SPINLOCK
(
tegra_powergate_lock
);
static
void
__iomem
*
tegra_pmc_base
;
static
bool
tegra_pmc_invert_interrupt
;
static
struct
clk
*
tegra_pclk
;
struct
pmc_pm_data
{
u32
cpu_good_time
;
/* CPU power good time in uS */
u32
cpu_off_time
;
/* CPU power off time in uS */
u32
core_osc_time
;
/* Core power good osc time in uS */
u32
core_pmu_time
;
/* Core power good pmu time in uS */
u32
core_off_time
;
/* Core power off time in uS */
bool
corereq_high
;
/* Core power request active-high */
bool
sysclkreq_high
;
/* System clock request active-high */
bool
combined_req
;
/* Combined pwr req for CPU & Core */
bool
cpu_pwr_good_en
;
/* CPU power good signal is enabled */
u32
lp0_vec_phy_addr
;
/* The phy addr of LP0 warm boot code */
u32
lp0_vec_size
;
/* The size of LP0 warm boot code */
enum
tegra_suspend_mode
suspend_mode
;
};
static
struct
pmc_pm_data
pmc_pm_data
;
static
inline
u32
tegra_pmc_readl
(
u32
reg
)
{
return
readl
(
IO_ADDRESS
(
TEGRA_PMC_BASE
+
reg
)
);
return
readl
(
tegra_pmc_base
+
reg
);
}
static
inline
void
tegra_pmc_writel
(
u32
val
,
u32
reg
)
{
writel
(
val
,
IO_ADDRESS
(
TEGRA_PMC_BASE
+
reg
));
writel
(
val
,
tegra_pmc_base
+
reg
);
}
static
int
tegra_pmc_get_cpu_powerdomain_id
(
int
cpuid
)
{
if
(
cpuid
<=
0
||
cpuid
>=
num_possible_cpus
())
return
-
EINVAL
;
return
tegra_cpu_domains
[
cpuid
];
}
static
bool
tegra_pmc_powergate_is_powered
(
int
id
)
{
return
(
tegra_pmc_readl
(
PMC_PWRGATE_STATUS
)
>>
id
)
&
1
;
}
static
int
tegra_pmc_powergate_set
(
int
id
,
bool
new_state
)
{
bool
old_state
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
tegra_powergate_lock
,
flags
);
old_state
=
tegra_pmc_powergate_is_powered
(
id
);
WARN_ON
(
old_state
==
new_state
);
tegra_pmc_writel
(
PMC_PWRGATE_TOGGLE_START
|
id
,
PMC_PWRGATE_TOGGLE
);
spin_unlock_irqrestore
(
&
tegra_powergate_lock
,
flags
);
return
0
;
}
static
int
tegra_pmc_powergate_remove_clamping
(
int
id
)
{
u32
mask
;
/*
* Tegra has a bug where PCIE and VDE clamping masks are
* swapped relatively to the partition ids.
*/
if
(
id
==
TEGRA_POWERGATE_VDEC
)
mask
=
(
1
<<
TEGRA_POWERGATE_PCIE
);
else
if
(
id
==
TEGRA_POWERGATE_PCIE
)
mask
=
(
1
<<
TEGRA_POWERGATE_VDEC
);
else
mask
=
(
1
<<
id
);
tegra_pmc_writel
(
mask
,
PMC_REMOVE_CLAMPING
);
return
0
;
}
bool
tegra_pmc_cpu_is_powered
(
int
cpuid
)
{
int
id
;
id
=
tegra_pmc_get_cpu_powerdomain_id
(
cpuid
);
if
(
id
<
0
)
return
false
;
return
tegra_pmc_powergate_is_powered
(
id
);
}
#ifdef CONFIG_OF
int
tegra_pmc_cpu_power_on
(
int
cpuid
)
{
int
id
;
id
=
tegra_pmc_get_cpu_powerdomain_id
(
cpuid
);
if
(
id
<
0
)
return
id
;
return
tegra_pmc_powergate_set
(
id
,
true
);
}
int
tegra_pmc_cpu_remove_clamping
(
int
cpuid
)
{
int
id
;
id
=
tegra_pmc_get_cpu_powerdomain_id
(
cpuid
);
if
(
id
<
0
)
return
id
;
return
tegra_pmc_powergate_remove_clamping
(
id
);
}
#ifdef CONFIG_PM_SLEEP
static
void
set_power_timers
(
u32
us_on
,
u32
us_off
,
unsigned
long
rate
)
{
unsigned
long
long
ticks
;
unsigned
long
long
pclk
;
static
unsigned
long
tegra_last_pclk
;
if
(
WARN_ON_ONCE
(
rate
<=
0
))
pclk
=
100000000
;
else
pclk
=
rate
;
if
((
rate
!=
tegra_last_pclk
))
{
ticks
=
(
us_on
*
pclk
)
+
999999ull
;
do_div
(
ticks
,
1000000
);
tegra_pmc_writel
((
unsigned
long
)
ticks
,
PMC_CPUPWRGOOD_TIMER
);
ticks
=
(
us_off
*
pclk
)
+
999999ull
;
do_div
(
ticks
,
1000000
);
tegra_pmc_writel
((
unsigned
long
)
ticks
,
PMC_CPUPWROFF_TIMER
);
wmb
();
}
tegra_last_pclk
=
pclk
;
}
enum
tegra_suspend_mode
tegra_pmc_get_suspend_mode
(
void
)
{
return
pmc_pm_data
.
suspend_mode
;
}
void
tegra_pmc_pm_set
(
enum
tegra_suspend_mode
mode
)
{
u32
reg
;
unsigned
long
rate
=
0
;
reg
=
tegra_pmc_readl
(
PMC_CTRL
);
reg
|=
TEGRA_POWER_CPU_PWRREQ_OE
;
reg
&=
~
TEGRA_POWER_EFFECT_LP0
;
switch
(
mode
)
{
case
TEGRA_SUSPEND_LP2
:
rate
=
clk_get_rate
(
tegra_pclk
);
break
;
default:
break
;
}
set_power_timers
(
pmc_pm_data
.
cpu_good_time
,
pmc_pm_data
.
cpu_off_time
,
rate
);
tegra_pmc_writel
(
reg
,
PMC_CTRL
);
}
void
tegra_pmc_suspend_init
(
void
)
{
u32
reg
;
/* Always enable CPU power request */
reg
=
tegra_pmc_readl
(
PMC_CTRL
);
reg
|=
TEGRA_POWER_CPU_PWRREQ_OE
;
tegra_pmc_writel
(
reg
,
PMC_CTRL
);
}
#endif
static
const
struct
of_device_id
matches
[]
__initconst
=
{
{
.
compatible
=
"nvidia,tegra114-pmc"
},
{
.
compatible
=
"nvidia,tegra30-pmc"
},
{
.
compatible
=
"nvidia,tegra20-pmc"
},
{
}
};
#endif
void
__init
tegra_pmc_ini
t
(
void
)
static
void
tegra_pmc_parse_d
t
(
void
)
{
/*
* For now, Harmony is the only board that uses the PMC, and it wants
* the signal inverted. Seaboard would too if it used the PMC.
* Hopefully by the time other boards want to use the PMC, everything
* will be device-tree, or they also want it inverted.
*/
bool
invert_interrupt
=
true
;
u32
val
;
struct
device_node
*
np
;
u32
prop
;
enum
tegra_suspend_mode
suspend_mode
;
u32
core_good_time
[
2
]
=
{
0
,
0
};
u32
lp0_vec
[
2
]
=
{
0
,
0
};
#ifdef CONFIG_OF
if
(
of_have_populated_dt
())
{
struct
device_node
*
np
;
np
=
of_find_matching_node
(
NULL
,
matches
);
BUG_ON
(
!
np
);
invert_interrupt
=
false
;
tegra_pmc_base
=
of_iomap
(
np
,
0
)
;
np
=
of_find_matching_node
(
NULL
,
matches
);
if
(
np
)
{
if
(
of_find_property
(
np
,
"nvidia,invert-interrupt"
,
NULL
))
invert_interrupt
=
true
;
tegra_pmc_invert_interrupt
=
of_property_read_bool
(
np
,
"nvidia,invert-interrupt"
);
tegra_pclk
=
of_clk_get_by_name
(
np
,
"pclk"
);
WARN_ON
(
IS_ERR
(
tegra_pclk
));
/* Grabbing the power management configurations */
if
(
of_property_read_u32
(
np
,
"nvidia,suspend-mode"
,
&
prop
))
{
suspend_mode
=
TEGRA_SUSPEND_NONE
;
}
else
{
switch
(
prop
)
{
case
0
:
suspend_mode
=
TEGRA_SUSPEND_LP0
;
break
;
case
1
:
suspend_mode
=
TEGRA_SUSPEND_LP1
;
break
;
case
2
:
suspend_mode
=
TEGRA_SUSPEND_LP2
;
break
;
default:
suspend_mode
=
TEGRA_SUSPEND_NONE
;
break
;
}
}
#endif
suspend_mode
=
tegra_pm_validate_suspend_mode
(
suspend_mode
);
if
(
of_property_read_u32
(
np
,
"nvidia,cpu-pwr-good-time"
,
&
prop
))
suspend_mode
=
TEGRA_SUSPEND_NONE
;
pmc_pm_data
.
cpu_good_time
=
prop
;
if
(
of_property_read_u32
(
np
,
"nvidia,cpu-pwr-off-time"
,
&
prop
))
suspend_mode
=
TEGRA_SUSPEND_NONE
;
pmc_pm_data
.
cpu_off_time
=
prop
;
if
(
of_property_read_u32_array
(
np
,
"nvidia,core-pwr-good-time"
,
core_good_time
,
ARRAY_SIZE
(
core_good_time
)))
suspend_mode
=
TEGRA_SUSPEND_NONE
;
pmc_pm_data
.
core_osc_time
=
core_good_time
[
0
];
pmc_pm_data
.
core_pmu_time
=
core_good_time
[
1
];
if
(
of_property_read_u32
(
np
,
"nvidia,core-pwr-off-time"
,
&
prop
))
suspend_mode
=
TEGRA_SUSPEND_NONE
;
pmc_pm_data
.
core_off_time
=
prop
;
pmc_pm_data
.
corereq_high
=
of_property_read_bool
(
np
,
"nvidia,core-power-req-active-high"
);
pmc_pm_data
.
sysclkreq_high
=
of_property_read_bool
(
np
,
"nvidia,sys-clock-req-active-high"
);
pmc_pm_data
.
combined_req
=
of_property_read_bool
(
np
,
"nvidia,combined-power-req"
);
pmc_pm_data
.
cpu_pwr_good_en
=
of_property_read_bool
(
np
,
"nvidia,cpu-pwr-good-en"
);
if
(
of_property_read_u32_array
(
np
,
"nvidia,lp0-vec"
,
lp0_vec
,
ARRAY_SIZE
(
lp0_vec
)))
if
(
suspend_mode
==
TEGRA_SUSPEND_LP0
)
suspend_mode
=
TEGRA_SUSPEND_LP1
;
pmc_pm_data
.
lp0_vec_phy_addr
=
lp0_vec
[
0
];
pmc_pm_data
.
lp0_vec_size
=
lp0_vec
[
1
];
pmc_pm_data
.
suspend_mode
=
suspend_mode
;
}
void
__init
tegra_pmc_init
(
void
)
{
u32
val
;
tegra_pmc_parse_dt
();
val
=
tegra_pmc_readl
(
PMC_CTRL
);
if
(
invert_interrupt
)
if
(
tegra_pmc_
invert_interrupt
)
val
|=
PMC_CTRL_INTR_LOW
;
else
val
&=
~
PMC_CTRL_INTR_LOW
;
...
...
arch/arm/mach-tegra/pmc.h
View file @
8aa15d82
...
...
@@ -18,6 +18,24 @@
#ifndef __MACH_TEGRA_PMC_H
#define __MACH_TEGRA_PMC_H
enum
tegra_suspend_mode
{
TEGRA_SUSPEND_NONE
=
0
,
TEGRA_SUSPEND_LP2
,
/* CPU voltage off */
TEGRA_SUSPEND_LP1
,
/* CPU voltage off, DRAM self-refresh */
TEGRA_SUSPEND_LP0
,
/* CPU + core voltage off, DRAM self-refresh */
TEGRA_MAX_SUSPEND_MODE
,
};
#ifdef CONFIG_PM_SLEEP
enum
tegra_suspend_mode
tegra_pmc_get_suspend_mode
(
void
);
void
tegra_pmc_pm_set
(
enum
tegra_suspend_mode
mode
);
void
tegra_pmc_suspend_init
(
void
);
#endif
bool
tegra_pmc_cpu_is_powered
(
int
cpuid
);
int
tegra_pmc_cpu_power_on
(
int
cpuid
);
int
tegra_pmc_cpu_remove_clamping
(
int
cpuid
);
void
tegra_pmc_init
(
void
);
#endif
arch/arm/mach-tegra/reset-handler.S
View file @
8aa15d82
...
...
@@ -41,9 +41,6 @@
*/
ENTRY
(
tegra_resume
)
bl
v7_invalidate_l1
/
*
Enable
coresight
*/
mov32
r0
,
0xC5ACCE55
mcr
p14
,
0
,
r0
,
c7
,
c12
,
6
cpu_id
r0
cmp
r0
,
#
0
@
CPU0
?
...
...
@@ -99,6 +96,8 @@ ENTRY(__tegra_cpu_reset_handler_start)
*
*
Register
usage
within
the
reset
handler
:
*
*
Others
:
scratch
*
R6
=
SoC
ID
<<
8
*
R7
=
CPU
present
(
to
the
OS
)
mask
*
R8
=
CPU
in
LP1
state
mask
*
R9
=
CPU
in
LP2
state
mask
...
...
@@ -114,6 +113,40 @@ ENTRY(__tegra_cpu_reset_handler_start)
ENTRY
(
__tegra_cpu_reset_handler
)
cpsid
aif
,
0x13
@
SVC
mode
,
interrupts
disabled
mov32
r6
,
TEGRA_APB_MISC_BASE
ldr
r6
,
[
r6
,
#
APB_MISC_GP_HIDREV
]
and
r6
,
r6
,
#
0xff00
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
t20_check
:
cmp
r6
,
#(
0x20
<<
8
)
bne
after_t20_check
t20_errata
:
#
Tegra20
is
a
Cortex
-
A9
r1p1
mrc
p15
,
0
,
r0
,
c1
,
c0
,
0
@
read
system
control
register
orr
r0
,
r0
,
#
1
<<
14
@
erratum
716044
mcr
p15
,
0
,
r0
,
c1
,
c0
,
0
@
write
system
control
register
mrc
p15
,
0
,
r0
,
c15
,
c0
,
1
@
read
diagnostic
register
orr
r0
,
r0
,
#
1
<<
4
@
erratum
742230
orr
r0
,
r0
,
#
1
<<
11
@
erratum
751472
mcr
p15
,
0
,
r0
,
c15
,
c0
,
1
@
write
diagnostic
register
b
after_errata
after_t20_check
:
#endif
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
t30_check
:
cmp
r6
,
#(
0x30
<<
8
)
bne
after_t30_check
t30_errata
:
#
Tegra30
is
a
Cortex
-
A9
r2p9
mrc
p15
,
0
,
r0
,
c15
,
c0
,
1
@
read
diagnostic
register
orr
r0
,
r0
,
#
1
<<
6
@
erratum
743622
orr
r0
,
r0
,
#
1
<<
11
@
erratum
751472
mcr
p15
,
0
,
r0
,
c15
,
c0
,
1
@
write
diagnostic
register
b
after_errata
after_t30_check
:
#endif
after_errata
:
mrc
p15
,
0
,
r10
,
c0
,
c0
,
5
@
MPIDR
and
r10
,
r10
,
#
0x3
@
R10
=
CPU
number
mov
r11
,
#
1
...
...
@@ -129,16 +162,13 @@ ENTRY(__tegra_cpu_reset_handler)
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
/
*
Are
we
on
Tegra20
?
*/
mov32
r6
,
TEGRA_APB_MISC_BASE
ldr
r0
,
[
r6
,
#
APB_MISC_GP_HIDREV
]
and
r0
,
r0
,
#
0xff00
cmp
r0
,
#(
0x20
<<
8
)
cmp
r6
,
#(
0x20
<<
8
)
bne
1
f
/
*
If
not
CPU0
,
don
't let CPU0 reset CPU1 now that CPU1 is coming up. */
mov32
r
6
,
TEGRA_PMC_BASE
mov32
r
5
,
TEGRA_PMC_BASE
mov
r0
,
#
0
cmp
r10
,
#
0
strne
r0
,
[
r
6
,
#
PMC_SCRATCH41
]
strne
r0
,
[
r
5
,
#
PMC_SCRATCH41
]
1
:
#endif
...
...
arch/arm/mach-tegra/sleep.h
View file @
8aa15d82
/*
* Copyright (c) 2010-201
2
, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2010-201
3
, NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
...
...
@@ -124,11 +124,11 @@ int tegra_sleep_cpu_finish(unsigned long);
void
tegra_disable_clean_inv_dcache
(
void
);
#ifdef CONFIG_HOTPLUG_CPU
void
tegra20_hotplug_init
(
void
);
void
tegra30_hotplug_init
(
void
);
void
tegra20_hotplug_shutdown
(
void
);
void
tegra30_hotplug_shutdown
(
void
);
void
tegra_hotplug_init
(
void
);
#else
static
inline
void
tegra20_hotplug_init
(
void
)
{}
static
inline
void
tegra30_hotplug_init
(
void
)
{}
static
inline
void
tegra_hotplug_init
(
void
)
{}
#endif
void
tegra20_cpu_shutdown
(
int
cpu
);
...
...
arch/arm/mach-tegra/
board-dt-tegra20
.c
→
arch/arm/mach-tegra/
tegra
.c
View file @
8aa15d82
/*
*
nVidia Tegra
device tree board support
*
NVIDIA Tegra SoC
device tree board support
*
* Copyright (C) 2011, 2013, NVIDIA Corporation
* Copyright (C) 2010 Secret Lab Technologies, Ltd.
* Copyright (C) 2010 Google, Inc.
*
...
...
@@ -32,6 +33,8 @@
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c-tegra.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
#include <linux/usb/tegra_usb_phy.h>
#include <asm/mach-types.h>
...
...
@@ -41,6 +44,7 @@
#include "board.h"
#include "common.h"
#include "fuse.h"
#include "iomap.h"
static
struct
tegra_ehci_platform_data
tegra_ehci1_pdata
=
{
...
...
@@ -79,12 +83,36 @@ static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
static
void
__init
tegra_dt_init
(
void
)
{
struct
soc_device_attribute
*
soc_dev_attr
;
struct
soc_device
*
soc_dev
;
struct
device
*
parent
=
NULL
;
soc_dev_attr
=
kzalloc
(
sizeof
(
*
soc_dev_attr
),
GFP_KERNEL
);
if
(
!
soc_dev_attr
)
goto
out
;
soc_dev_attr
->
family
=
kasprintf
(
GFP_KERNEL
,
"Tegra"
);
soc_dev_attr
->
revision
=
kasprintf
(
GFP_KERNEL
,
"%d"
,
tegra_revision
);
soc_dev_attr
->
soc_id
=
kasprintf
(
GFP_KERNEL
,
"%d"
,
tegra_chip_id
);
soc_dev
=
soc_device_register
(
soc_dev_attr
);
if
(
IS_ERR
(
soc_dev
))
{
kfree
(
soc_dev_attr
->
family
);
kfree
(
soc_dev_attr
->
revision
);
kfree
(
soc_dev_attr
->
soc_id
);
kfree
(
soc_dev_attr
);
goto
out
;
}
parent
=
soc_device_to_device
(
soc_dev
);
/*
* Finished with the static registrations now; fill in the missing
* devices
*/
out:
of_platform_populate
(
NULL
,
of_default_bus_match_table
,
tegra20_auxdata_lookup
,
NULL
);
tegra20_auxdata_lookup
,
parent
);
}
static
void
__init
trimslice_init
(
void
)
...
...
@@ -111,7 +139,8 @@ static void __init harmony_init(void)
static
void
__init
paz00_init
(
void
)
{
tegra_paz00_wifikill_init
();
if
(
IS_ENABLED
(
CONFIG_ARCH_TEGRA_2x_SOC
))
tegra_paz00_wifikill_init
();
}
static
struct
{
...
...
@@ -137,19 +166,21 @@ static void __init tegra_dt_init_late(void)
}
}
static
const
char
*
tegra20_dt_board_compat
[]
=
{
static
const
char
*
const
tegra_dt_board_compat
[]
=
{
"nvidia,tegra114"
,
"nvidia,tegra30"
,
"nvidia,tegra20"
,
NULL
};
DT_MACHINE_START
(
TEGRA_DT
,
"
nVidia Tegra20
(Flattened Device Tree)"
)
DT_MACHINE_START
(
TEGRA_DT
,
"
NVIDIA Tegra SoC
(Flattened Device Tree)"
)
.
map_io
=
tegra_map_common_io
,
.
smp
=
smp_ops
(
tegra_smp_ops
),
.
init_early
=
tegra
20
_init_early
,
.
init_early
=
tegra_init_early
,
.
init_irq
=
tegra_dt_init_irq
,
.
init_time
=
clocksource_of_init
,
.
init_machine
=
tegra_dt_init
,
.
init_late
=
tegra_dt_init_late
,
.
restart
=
tegra_assert_system_reset
,
.
dt_compat
=
tegra
20
_dt_board_compat
,
.
dt_compat
=
tegra_dt_board_compat
,
MACHINE_END
arch/arm/mach-tegra/tegra114_speedo.c
0 → 100644
View file @
8aa15d82
/*
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
#include <linux/bug.h>
#include "fuse.h"
#define CORE_PROCESS_CORNERS_NUM 2
#define CPU_PROCESS_CORNERS_NUM 2
enum
{
THRESHOLD_INDEX_0
,
THRESHOLD_INDEX_1
,
THRESHOLD_INDEX_COUNT
,
};
static
const
u32
core_process_speedos
[][
CORE_PROCESS_CORNERS_NUM
]
=
{
{
1123
,
UINT_MAX
},
{
0
,
UINT_MAX
},
};
static
const
u32
cpu_process_speedos
[][
CPU_PROCESS_CORNERS_NUM
]
=
{
{
1695
,
UINT_MAX
},
{
0
,
UINT_MAX
},
};
static
void
rev_sku_to_speedo_ids
(
int
rev
,
int
sku
,
int
*
threshold
)
{
u32
tmp
;
switch
(
sku
)
{
case
0x00
:
case
0x10
:
case
0x05
:
case
0x06
:
tegra_cpu_speedo_id
=
1
;
tegra_soc_speedo_id
=
0
;
*
threshold
=
THRESHOLD_INDEX_0
;
break
;
case
0x03
:
case
0x04
:
tegra_cpu_speedo_id
=
2
;
tegra_soc_speedo_id
=
1
;
*
threshold
=
THRESHOLD_INDEX_1
;
break
;
default:
pr_err
(
"Tegra114 Unknown SKU %d
\n
"
,
sku
);
tegra_cpu_speedo_id
=
0
;
tegra_soc_speedo_id
=
0
;
*
threshold
=
THRESHOLD_INDEX_0
;
break
;
}
if
(
rev
==
TEGRA_REVISION_A01
)
{
tmp
=
tegra_fuse_readl
(
0x270
)
<<
1
;
tmp
|=
tegra_fuse_readl
(
0x26c
);
if
(
!
tmp
)
tegra_cpu_speedo_id
=
0
;
}
}
void
tegra114_init_speedo_data
(
void
)
{
u32
cpu_speedo_val
;
u32
core_speedo_val
;
int
threshold
;
int
i
;
BUILD_BUG_ON
(
ARRAY_SIZE
(
cpu_process_speedos
)
!=
THRESHOLD_INDEX_COUNT
);
BUILD_BUG_ON
(
ARRAY_SIZE
(
core_process_speedos
)
!=
THRESHOLD_INDEX_COUNT
);
rev_sku_to_speedo_ids
(
tegra_revision
,
tegra_sku_id
,
&
threshold
);
cpu_speedo_val
=
tegra_fuse_readl
(
0x12c
)
+
1024
;
core_speedo_val
=
tegra_fuse_readl
(
0x134
);
for
(
i
=
0
;
i
<
CPU_PROCESS_CORNERS_NUM
;
i
++
)
if
(
cpu_speedo_val
<
cpu_process_speedos
[
threshold
][
i
])
break
;
tegra_cpu_process_id
=
i
;
for
(
i
=
0
;
i
<
CORE_PROCESS_CORNERS_NUM
;
i
++
)
if
(
core_speedo_val
<
core_process_speedos
[
threshold
][
i
])
break
;
tegra_core_process_id
=
i
;
}
drivers/clk/tegra/clk-tegra20.c
View file @
8aa15d82
...
...
@@ -711,8 +711,8 @@ static void tegra20_pll_init(void)
}
static
const
char
*
cclk_parents
[]
=
{
"clk_m"
,
"pll_c"
,
"clk_32k"
,
"pll_m"
,
"pll_p
_cclk"
,
"pll_p_out4_cclk
"
,
"pll_p_out3
_cclk
"
,
"clk_d"
,
"pll_x"
};
"pll_p
"
,
"pll_p_out4
"
,
"pll_p_out3"
,
"clk_d"
,
"pll_x"
};
static
const
char
*
sclk_parents
[]
=
{
"clk_m"
,
"pll_c_out1"
,
"pll_p_out4"
,
"pll_p_out3"
,
"pll_p_out2"
,
"clk_d"
,
"clk_32k"
,
"pll_m_out1"
};
...
...
@@ -721,38 +721,6 @@ static void tegra20_super_clk_init(void)
{
struct
clk
*
clk
;
/*
* DIV_U71 dividers for CCLK, these dividers are used only
* if parent clock is fixed rate.
*/
/*
* Clock input to cclk divided from pll_p using
* U71 divider of cclk.
*/
clk
=
tegra_clk_register_divider
(
"pll_p_cclk"
,
"pll_p"
,
clk_base
+
SUPER_CCLK_DIVIDER
,
0
,
TEGRA_DIVIDER_INT
,
16
,
8
,
1
,
NULL
);
clk_register_clkdev
(
clk
,
"pll_p_cclk"
,
NULL
);
/*
* Clock input to cclk divided from pll_p_out3 using
* U71 divider of cclk.
*/
clk
=
tegra_clk_register_divider
(
"pll_p_out3_cclk"
,
"pll_p_out3"
,
clk_base
+
SUPER_CCLK_DIVIDER
,
0
,
TEGRA_DIVIDER_INT
,
16
,
8
,
1
,
NULL
);
clk_register_clkdev
(
clk
,
"pll_p_out3_cclk"
,
NULL
);
/*
* Clock input to cclk divided from pll_p_out4 using
* U71 divider of cclk.
*/
clk
=
tegra_clk_register_divider
(
"pll_p_out4_cclk"
,
"pll_p_out4"
,
clk_base
+
SUPER_CCLK_DIVIDER
,
0
,
TEGRA_DIVIDER_INT
,
16
,
8
,
1
,
NULL
);
clk_register_clkdev
(
clk
,
"pll_p_out4_cclk"
,
NULL
);
/* CCLK */
clk
=
tegra_clk_register_super_mux
(
"cclk"
,
cclk_parents
,
ARRAY_SIZE
(
cclk_parents
),
CLK_SET_RATE_PARENT
,
...
...
drivers/clocksource/tegra20_timer.c
View file @
8aa15d82
...
...
@@ -189,7 +189,7 @@ static void __init tegra20_init_timer(void)
BUG
();
}
clk
=
clk_get_sys
(
"timer"
,
NULL
);
clk
=
of_clk_get
(
np
,
0
);
if
(
IS_ERR
(
clk
))
{
pr_warn
(
"Unable to get timer clock. Assuming 12Mhz input clock.
\n
"
);
rate
=
12000000
;
...
...
@@ -216,7 +216,7 @@ static void __init tegra20_init_timer(void)
* rtc registers are used by read_persistent_clock, keep the rtc clock
* enabled
*/
clk
=
clk_get_sys
(
"rtc-tegra"
,
NULL
);
clk
=
of_clk_get
(
np
,
0
);
if
(
IS_ERR
(
clk
))
pr_warn
(
"Unable to get rtc-tegra clock
\n
"
);
else
...
...
drivers/gpio/gpio-tegra.c
View file @
8aa15d82
...
...
@@ -72,6 +72,7 @@ struct tegra_gpio_bank {
u32
oe
[
4
];
u32
int_enb
[
4
];
u32
int_lvl
[
4
];
u32
wake_enb
[
4
];
#endif
};
...
...
@@ -333,15 +334,31 @@ static int tegra_gpio_suspend(struct device *dev)
bank
->
oe
[
p
]
=
tegra_gpio_readl
(
GPIO_OE
(
gpio
));
bank
->
int_enb
[
p
]
=
tegra_gpio_readl
(
GPIO_INT_ENB
(
gpio
));
bank
->
int_lvl
[
p
]
=
tegra_gpio_readl
(
GPIO_INT_LVL
(
gpio
));
/* Enable gpio irq for wake up source */
tegra_gpio_writel
(
bank
->
wake_enb
[
p
],
GPIO_INT_ENB
(
gpio
));
}
}
local_irq_restore
(
flags
);
return
0
;
}
static
int
tegra_gpio_
wake_enabl
e
(
struct
irq_data
*
d
,
unsigned
int
enable
)
static
int
tegra_gpio_
irq_set_wak
e
(
struct
irq_data
*
d
,
unsigned
int
enable
)
{
struct
tegra_gpio_bank
*
bank
=
irq_data_get_irq_chip_data
(
d
);
int
gpio
=
d
->
hwirq
;
u32
port
,
bit
,
mask
;
port
=
GPIO_PORT
(
gpio
);
bit
=
GPIO_BIT
(
gpio
);
mask
=
BIT
(
bit
);
if
(
enable
)
bank
->
wake_enb
[
port
]
|=
mask
;
else
bank
->
wake_enb
[
port
]
&=
~
mask
;
return
irq_set_irq_wake
(
bank
->
irq
,
enable
);
}
#endif
...
...
@@ -353,7 +370,7 @@ static struct irq_chip tegra_gpio_irq_chip = {
.
irq_unmask
=
tegra_gpio_irq_unmask
,
.
irq_set_type
=
tegra_gpio_irq_set_type
,
#ifdef CONFIG_PM_SLEEP
.
irq_set_wake
=
tegra_gpio_
wake_enabl
e
,
.
irq_set_wake
=
tegra_gpio_
irq_set_wak
e
,
#endif
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment