Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'tegra/soc' into next/multiplatform

This is a dependency for the tegra multiplatform series.

Conflicts:
drivers/clocksource/tegra20_timer.c

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+1046 -407
+66 -1
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
··· 1 1 NVIDIA Tegra Power Management Controller (PMC) 2 2 3 - Properties: 3 + The PMC block interacts with an external Power Management Unit. The PMC 4 + mostly controls the entry and exit of the system from different sleep 5 + modes. It provides power-gating controllers for SoC and CPU power-islands. 6 + 7 + Required properties: 4 8 - name : Should be pmc 5 9 - compatible : Should contain "nvidia,tegra<chip>-pmc". 6 10 - reg : Offset and length of the register set for the device 11 + - clocks : Must contain an entry for each entry in clock-names. 12 + - clock-names : Must include the following entries: 13 + "pclk" (The Tegra clock of that name), 14 + "clk32k_in" (The 32KHz clock input to Tegra). 15 + 16 + Optional properties: 7 17 - nvidia,invert-interrupt : If present, inverts the PMU interrupt signal. 8 18 The PMU is an external Power Management Unit, whose interrupt output 9 19 signal is fed into the PMC. This signal is optionally inverted, and then 10 20 fed into the ARM GIC. The PMC is not involved in the detection or 11 21 handling of this interrupt signal, merely its inversion. 22 + - nvidia,suspend-mode : The suspend mode that the platform should use. 23 + Valid values are 0, 1 and 2: 24 + 0 (LP0): CPU + Core voltage off and DRAM in self-refresh 25 + 1 (LP1): CPU voltage off and DRAM in self-refresh 26 + 2 (LP2): CPU voltage off 27 + - nvidia,core-power-req-active-high : Boolean, core power request active-high 28 + - nvidia,sys-clock-req-active-high : Boolean, system clock request active-high 29 + - nvidia,combined-power-req : Boolean, combined power request for CPU & Core 30 + - nvidia,cpu-pwr-good-en : Boolean, CPU power good signal (from PMIC to PMC) 31 + is enabled. 32 + 33 + Required properties when nvidia,suspend-mode is specified: 34 + - nvidia,cpu-pwr-good-time : CPU power good time in uS. 35 + - nvidia,cpu-pwr-off-time : CPU power off time in uS. 36 + - nvidia,core-pwr-good-time : <Oscillator-stable-time Power-stable-time> 37 + Core power good time in uS. 38 + - nvidia,core-pwr-off-time : Core power off time in uS. 39 + 40 + Required properties when nvidia,suspend-mode=<0>: 41 + - nvidia,lp0-vec : <start length> Starting address and length of LP0 vector 42 + The LP0 vector contains the warm boot code that is executed by AVP when 43 + resuming from the LP0 state. The AVP (Audio-Video Processor) is an ARM7 44 + processor and always being the first boot processor when chip is power on 45 + or resume from deep sleep mode. When the system is resumed from the deep 46 + sleep mode, the warm boot code will restore some PLLs, clocks and then 47 + bring up CPU0 for resuming the system. 12 48 13 49 Example: 14 50 51 + / SoC dts including file 15 52 pmc@7000f400 { 16 53 compatible = "nvidia,tegra20-pmc"; 17 54 reg = <0x7000e400 0x400>; 55 + clocks = <&tegra_car 110>, <&clk32k_in>; 56 + clock-names = "pclk", "clk32k_in"; 18 57 nvidia,invert-interrupt; 58 + nvidia,suspend-mode = <1>; 59 + nvidia,cpu-pwr-good-time = <2000>; 60 + nvidia,cpu-pwr-off-time = <100>; 61 + nvidia,core-pwr-good-time = <3845 3845>; 62 + nvidia,core-pwr-off-time = <458>; 63 + nvidia,core-power-req-active-high; 64 + nvidia,sys-clock-req-active-high; 65 + nvidia,lp0-vec = <0xbdffd000 0x2000>; 66 + }; 67 + 68 + / Tegra board dts file 69 + { 70 + ... 71 + clocks { 72 + compatible = "simple-bus"; 73 + #address-cells = <1>; 74 + #size-cells = <0>; 75 + 76 + clk32k_in: clock { 77 + compatible = "fixed-clock"; 78 + reg=<0>; 79 + #clock-cells = <0>; 80 + clock-frequency = <32768>; 81 + }; 82 + }; 83 + ... 19 84 };
+1
arch/arm/Kconfig
··· 612 612 select HAVE_CLK 613 613 select HAVE_SMP 614 614 select MIGHT_HAVE_CACHE_L2X0 615 + select SOC_BUS 615 616 select SPARSE_IRQ 616 617 select USE_OF 617 618 help
+13
arch/arm/boot/dts/tegra114-dalmore.dts
··· 18 18 pmc { 19 19 nvidia,invert-interrupt; 20 20 }; 21 + 22 + clocks { 23 + compatible = "simple-bus"; 24 + #address-cells = <1>; 25 + #size-cells = <0>; 26 + 27 + clk32k_in: clock { 28 + compatible = "fixed-clock"; 29 + reg=<0>; 30 + #clock-cells = <0>; 31 + clock-frequency = <32768>; 32 + }; 33 + }; 21 34 };
+13
arch/arm/boot/dts/tegra114-pluto.dts
··· 18 18 pmc { 19 19 nvidia,invert-interrupt; 20 20 }; 21 + 22 + clocks { 23 + compatible = "simple-bus"; 24 + #address-cells = <1>; 25 + #size-cells = <0>; 26 + 27 + clk32k_in: clock { 28 + compatible = "fixed-clock"; 29 + reg=<0>; 30 + #clock-cells = <0>; 31 + clock-frequency = <32768>; 32 + }; 33 + }; 21 34 };
+3 -1
arch/arm/boot/dts/tegra114.dtsi
··· 99 99 }; 100 100 101 101 pmc { 102 - compatible = "nvidia,tegra114-pmc", "nvidia,tegra30-pmc"; 102 + compatible = "nvidia,tegra114-pmc"; 103 103 reg = <0x7000e400 0x400>; 104 + clocks = <&tegra_car 261>, <&clk32k_in>; 105 + clock-names = "pclk", "clk32k_in"; 104 106 }; 105 107 106 108 iommu {
+14 -1
arch/arm/boot/dts/tegra20-colibri-512.dtsi
··· 444 444 }; 445 445 446 446 sdhci@c8000600 { 447 - cd-gpios = <&gpio 23 0>; /* gpio PC7 */ 447 + cd-gpios = <&gpio 23 1>; /* gpio PC7 */ 448 + }; 449 + 450 + clocks { 451 + compatible = "simple-bus"; 452 + #address-cells = <1>; 453 + #size-cells = <0>; 454 + 455 + clk32k_in: clock { 456 + compatible = "fixed-clock"; 457 + reg=<0>; 458 + #clock-cells = <0>; 459 + clock-frequency = <32768>; 460 + }; 448 461 }; 449 462 450 463 sound {
+15 -2
arch/arm/boot/dts/tegra20-harmony.dts
··· 437 437 438 438 sdhci@c8000200 { 439 439 status = "okay"; 440 - cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 440 + cd-gpios = <&gpio 69 1>; /* gpio PI5 */ 441 441 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 442 442 power-gpios = <&gpio 155 0>; /* gpio PT3 */ 443 443 bus-width = <4>; ··· 445 445 446 446 sdhci@c8000600 { 447 447 status = "okay"; 448 - cd-gpios = <&gpio 58 0>; /* gpio PH2 */ 448 + cd-gpios = <&gpio 58 1>; /* gpio PH2 */ 449 449 wp-gpios = <&gpio 59 0>; /* gpio PH3 */ 450 450 power-gpios = <&gpio 70 0>; /* gpio PI6 */ 451 451 bus-width = <8>; 452 + }; 453 + 454 + clocks { 455 + compatible = "simple-bus"; 456 + #address-cells = <1>; 457 + #size-cells = <0>; 458 + 459 + clk32k_in: clock { 460 + compatible = "fixed-clock"; 461 + reg=<0>; 462 + #clock-cells = <0>; 463 + clock-frequency = <32768>; 464 + }; 452 465 }; 453 466 454 467 kbc {
+14 -1
arch/arm/boot/dts/tegra20-paz00.dts
··· 436 436 437 437 sdhci@c8000000 { 438 438 status = "okay"; 439 - cd-gpios = <&gpio 173 0>; /* gpio PV5 */ 439 + cd-gpios = <&gpio 173 1>; /* gpio PV5 */ 440 440 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 441 441 power-gpios = <&gpio 169 0>; /* gpio PV1 */ 442 442 bus-width = <4>; ··· 445 445 sdhci@c8000600 { 446 446 status = "okay"; 447 447 bus-width = <8>; 448 + }; 449 + 450 + clocks { 451 + compatible = "simple-bus"; 452 + #address-cells = <1>; 453 + #size-cells = <0>; 454 + 455 + clk32k_in: clock { 456 + compatible = "fixed-clock"; 457 + reg=<0>; 458 + #clock-cells = <0>; 459 + clock-frequency = <32768>; 460 + }; 448 461 }; 449 462 450 463 gpio-keys {
+14 -1
arch/arm/boot/dts/tegra20-seaboard.dts
··· 584 584 585 585 sdhci@c8000400 { 586 586 status = "okay"; 587 - cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 587 + cd-gpios = <&gpio 69 1>; /* gpio PI5 */ 588 588 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 589 589 power-gpios = <&gpio 70 0>; /* gpio PI6 */ 590 590 bus-width = <4>; ··· 593 593 sdhci@c8000600 { 594 594 status = "okay"; 595 595 bus-width = <8>; 596 + }; 597 + 598 + clocks { 599 + compatible = "simple-bus"; 600 + #address-cells = <1>; 601 + #size-cells = <0>; 602 + 603 + clk32k_in: clock { 604 + compatible = "fixed-clock"; 605 + reg=<0>; 606 + #clock-cells = <0>; 607 + clock-frequency = <32768>; 608 + }; 596 609 }; 597 610 598 611 gpio-keys {
+14 -1
arch/arm/boot/dts/tegra20-tamonten.dtsi
··· 465 465 }; 466 466 467 467 sdhci@c8000600 { 468 - cd-gpios = <&gpio 58 0>; /* gpio PH2 */ 468 + cd-gpios = <&gpio 58 1>; /* gpio PH2 */ 469 469 wp-gpios = <&gpio 59 0>; /* gpio PH3 */ 470 470 bus-width = <4>; 471 471 status = "okay"; 472 + }; 473 + 474 + clocks { 475 + compatible = "simple-bus"; 476 + #address-cells = <1>; 477 + #size-cells = <0>; 478 + 479 + clk32k_in: clock { 480 + compatible = "fixed-clock"; 481 + reg=<0>; 482 + #clock-cells = <0>; 483 + clock-frequency = <32768>; 484 + }; 472 485 }; 473 486 474 487 regulators {
+14 -1
arch/arm/boot/dts/tegra20-trimslice.dts
··· 325 325 326 326 sdhci@c8000600 { 327 327 status = "okay"; 328 - cd-gpios = <&gpio 121 0>; /* gpio PP1 */ 328 + cd-gpios = <&gpio 121 1>; /* gpio PP1 */ 329 329 wp-gpios = <&gpio 122 0>; /* gpio PP2 */ 330 330 bus-width = <4>; 331 + }; 332 + 333 + clocks { 334 + compatible = "simple-bus"; 335 + #address-cells = <1>; 336 + #size-cells = <0>; 337 + 338 + clk32k_in: clock { 339 + compatible = "fixed-clock"; 340 + reg=<0>; 341 + #clock-cells = <0>; 342 + clock-frequency = <32768>; 343 + }; 331 344 }; 332 345 333 346 poweroff {
+14 -1
arch/arm/boot/dts/tegra20-ventana.dts
··· 520 520 521 521 sdhci@c8000400 { 522 522 status = "okay"; 523 - cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 523 + cd-gpios = <&gpio 69 1>; /* gpio PI5 */ 524 524 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 525 525 power-gpios = <&gpio 70 0>; /* gpio PI6 */ 526 526 bus-width = <4>; ··· 529 529 sdhci@c8000600 { 530 530 status = "okay"; 531 531 bus-width = <8>; 532 + }; 533 + 534 + clocks { 535 + compatible = "simple-bus"; 536 + #address-cells = <1>; 537 + #size-cells = <0>; 538 + 539 + clk32k_in: clock { 540 + compatible = "fixed-clock"; 541 + reg=<0>; 542 + #clock-cells = <0>; 543 + clock-frequency = <32768>; 544 + }; 532 545 }; 533 546 534 547 regulators {
+14
arch/arm/boot/dts/tegra20-whistler.dts
··· 510 510 511 511 sdhci@c8000400 { 512 512 status = "okay"; 513 + cd-gpios = <&gpio 69 1>; /* gpio PI5 */ 513 514 wp-gpios = <&gpio 173 0>; /* gpio PV5 */ 514 515 bus-width = <8>; 515 516 }; ··· 518 517 sdhci@c8000600 { 519 518 status = "okay"; 520 519 bus-width = <8>; 520 + }; 521 + 522 + clocks { 523 + compatible = "simple-bus"; 524 + #address-cells = <1>; 525 + #size-cells = <0>; 526 + 527 + clk32k_in: clock { 528 + compatible = "fixed-clock"; 529 + reg=<0>; 530 + #clock-cells = <0>; 531 + clock-frequency = <32768>; 532 + }; 521 533 }; 522 534 523 535 kbc {
+4
arch/arm/boot/dts/tegra20.dtsi
··· 145 145 0 1 0x04 146 146 0 41 0x04 147 147 0 42 0x04>; 148 + clocks = <&tegra_car 5>; 148 149 }; 149 150 150 151 tegra_car: clock { ··· 305 304 compatible = "nvidia,tegra20-rtc"; 306 305 reg = <0x7000e000 0x100>; 307 306 interrupts = <0 2 0x04>; 307 + clocks = <&tegra_car 4>; 308 308 }; 309 309 310 310 i2c@7000c000 { ··· 418 416 pmc { 419 417 compatible = "nvidia,tegra20-pmc"; 420 418 reg = <0x7000e400 0x400>; 419 + clocks = <&tegra_car 110>, <&clk32k_in>; 420 + clock-names = "pclk", "clk32k_in"; 421 421 }; 422 422 423 423 memory-controller@7000f000 {
+14 -1
arch/arm/boot/dts/tegra30-beaver.dts
··· 257 257 258 258 sdhci@78000000 { 259 259 status = "okay"; 260 - cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 260 + cd-gpios = <&gpio 69 1>; /* gpio PI5 */ 261 261 wp-gpios = <&gpio 155 0>; /* gpio PT3 */ 262 262 power-gpios = <&gpio 31 0>; /* gpio PD7 */ 263 263 bus-width = <4>; ··· 266 266 sdhci@78000600 { 267 267 status = "okay"; 268 268 bus-width = <8>; 269 + }; 270 + 271 + clocks { 272 + compatible = "simple-bus"; 273 + #address-cells = <1>; 274 + #size-cells = <0>; 275 + 276 + clk32k_in: clock { 277 + compatible = "fixed-clock"; 278 + reg=<0>; 279 + #clock-cells = <0>; 280 + clock-frequency = <32768>; 281 + }; 269 282 }; 270 283 271 284 regulators {
+14 -1
arch/arm/boot/dts/tegra30-cardhu.dtsi
··· 311 311 312 312 sdhci@78000000 { 313 313 status = "okay"; 314 - cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 314 + cd-gpios = <&gpio 69 1>; /* gpio PI5 */ 315 315 wp-gpios = <&gpio 155 0>; /* gpio PT3 */ 316 316 power-gpios = <&gpio 31 0>; /* gpio PD7 */ 317 317 bus-width = <4>; ··· 320 320 sdhci@78000600 { 321 321 status = "okay"; 322 322 bus-width = <8>; 323 + }; 324 + 325 + clocks { 326 + compatible = "simple-bus"; 327 + #address-cells = <1>; 328 + #size-cells = <0>; 329 + 330 + clk32k_in: clock { 331 + compatible = "fixed-clock"; 332 + reg=<0>; 333 + #clock-cells = <0>; 334 + clock-frequency = <32768>; 335 + }; 323 336 }; 324 337 325 338 regulators {
+5 -1
arch/arm/boot/dts/tegra30.dtsi
··· 148 148 0 42 0x04 149 149 0 121 0x04 150 150 0 122 0x04>; 151 + clocks = <&tegra_car 5>; 151 152 }; 152 153 153 154 tegra_car: clock { ··· 292 291 compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc"; 293 292 reg = <0x7000e000 0x100>; 294 293 interrupts = <0 2 0x04>; 294 + clocks = <&tegra_car 4>; 295 295 }; 296 296 297 297 i2c@7000c000 { ··· 425 423 }; 426 424 427 425 pmc { 428 - compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc"; 426 + compatible = "nvidia,tegra30-pmc"; 429 427 reg = <0x7000e400 0x400>; 428 + clocks = <&tegra_car 218>, <&clk32k_in>; 429 + clock-names = "pclk", "clk32k_in"; 430 430 }; 431 431 432 432 memory-controller {
+2 -3
arch/arm/mach-tegra/Makefile
··· 10 10 obj-y += reset.o 11 11 obj-y += reset-handler.o 12 12 obj-y += sleep.o 13 + obj-y += tegra.o 13 14 obj-$(CONFIG_CPU_IDLE) += cpuidle.o 14 15 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o 15 16 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o ··· 28 27 obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o 29 28 obj-$(CONFIG_TEGRA_PCI) += pcie.o 30 29 31 - obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o 32 - obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o 33 - obj-$(CONFIG_ARCH_TEGRA_114_SOC) += board-dt-tegra114.o 30 + obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o 34 31 ifeq ($(CONFIG_CPU_IDLE),y) 35 32 obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o 36 33 endif
-46
arch/arm/mach-tegra/board-dt-tegra114.c
··· 1 - /* 2 - * NVIDIA Tegra114 device tree board support 3 - * 4 - * Copyright (C) 2013 NVIDIA Corporation 5 - * 6 - * This software is licensed under the terms of the GNU General Public 7 - * License version 2, as published by the Free Software Foundation, and 8 - * may be copied, distributed, and modified under those terms. 9 - * 10 - * This program is distributed in the hope that it will be useful, 11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 - * GNU General Public License for more details. 14 - * 15 - */ 16 - 17 - #include <linux/of.h> 18 - #include <linux/of_platform.h> 19 - #include <linux/clocksource.h> 20 - 21 - #include <asm/mach/arch.h> 22 - 23 - #include "board.h" 24 - #include "common.h" 25 - 26 - static void __init tegra114_dt_init(void) 27 - { 28 - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 29 - } 30 - 31 - static const char * const tegra114_dt_board_compat[] = { 32 - "nvidia,tegra114", 33 - NULL, 34 - }; 35 - 36 - DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)") 37 - .smp = smp_ops(tegra_smp_ops), 38 - .map_io = tegra_map_common_io, 39 - .init_early = tegra114_init_early, 40 - .init_irq = tegra_dt_init_irq, 41 - .init_time = clocksource_of_init, 42 - .init_machine = tegra114_dt_init, 43 - .init_late = tegra_init_late, 44 - .restart = tegra_assert_system_reset, 45 - .dt_compat = tegra114_dt_board_compat, 46 - MACHINE_END
+38 -7
arch/arm/mach-tegra/board-dt-tegra20.c arch/arm/mach-tegra/tegra.c
··· 1 1 /* 2 - * nVidia Tegra device tree board support 2 + * NVIDIA Tegra SoC device tree board support 3 3 * 4 + * Copyright (C) 2011, 2013, NVIDIA Corporation 4 5 * Copyright (C) 2010 Secret Lab Technologies, Ltd. 5 6 * Copyright (C) 2010 Google, Inc. 6 7 * ··· 33 32 #include <linux/io.h> 34 33 #include <linux/i2c.h> 35 34 #include <linux/i2c-tegra.h> 35 + #include <linux/slab.h> 36 + #include <linux/sys_soc.h> 36 37 #include <linux/usb/tegra_usb_phy.h> 37 38 38 39 #include <asm/mach-types.h> ··· 44 41 45 42 #include "board.h" 46 43 #include "common.h" 44 + #include "fuse.h" 47 45 #include "iomap.h" 48 46 49 47 static struct tegra_ehci_platform_data tegra_ehci1_pdata = { ··· 83 79 84 80 static void __init tegra_dt_init(void) 85 81 { 82 + struct soc_device_attribute *soc_dev_attr; 83 + struct soc_device *soc_dev; 84 + struct device *parent = NULL; 85 + 86 + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); 87 + if (!soc_dev_attr) 88 + goto out; 89 + 90 + soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra"); 91 + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_revision); 92 + soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", tegra_chip_id); 93 + 94 + soc_dev = soc_device_register(soc_dev_attr); 95 + if (IS_ERR(soc_dev)) { 96 + kfree(soc_dev_attr->family); 97 + kfree(soc_dev_attr->revision); 98 + kfree(soc_dev_attr->soc_id); 99 + kfree(soc_dev_attr); 100 + goto out; 101 + } 102 + 103 + parent = soc_device_to_device(soc_dev); 104 + 86 105 /* 87 106 * Finished with the static registrations now; fill in the missing 88 107 * devices 89 108 */ 109 + out: 90 110 of_platform_populate(NULL, of_default_bus_match_table, 91 - tegra20_auxdata_lookup, NULL); 111 + tegra20_auxdata_lookup, parent); 92 112 } 93 113 94 114 static void __init trimslice_init(void) ··· 139 111 140 112 static void __init paz00_init(void) 141 113 { 142 - tegra_paz00_wifikill_init(); 114 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 115 + tegra_paz00_wifikill_init(); 143 116 } 144 117 145 118 static struct { ··· 166 137 } 167 138 } 168 139 169 - static const char *tegra20_dt_board_compat[] = { 140 + static const char * const tegra_dt_board_compat[] = { 141 + "nvidia,tegra114", 142 + "nvidia,tegra30", 170 143 "nvidia,tegra20", 171 144 NULL 172 145 }; 173 146 174 - DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)") 147 + DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)") 175 148 .map_io = tegra_map_common_io, 176 149 .smp = smp_ops(tegra_smp_ops), 177 - .init_early = tegra20_init_early, 150 + .init_early = tegra_init_early, 178 151 .init_irq = tegra_dt_init_irq, 179 152 .init_time = clocksource_of_init, 180 153 .init_machine = tegra_dt_init, 181 154 .init_late = tegra_dt_init_late, 182 155 .restart = tegra_assert_system_reset, 183 - .dt_compat = tegra20_dt_board_compat, 156 + .dt_compat = tegra_dt_board_compat, 184 157 MACHINE_END
-60
arch/arm/mach-tegra/board-dt-tegra30.c
··· 1 - /* 2 - * arch/arm/mach-tegra/board-dt-tegra30.c 3 - * 4 - * NVIDIA Tegra30 device tree board support 5 - * 6 - * Copyright (C) 2011 NVIDIA Corporation 7 - * 8 - * Derived from: 9 - * 10 - * arch/arm/mach-tegra/board-dt-tegra20.c 11 - * 12 - * Copyright (C) 2010 Secret Lab Technologies, Ltd. 13 - * Copyright (C) 2010 Google, Inc. 14 - * 15 - * This software is licensed under the terms of the GNU General Public 16 - * License version 2, as published by the Free Software Foundation, and 17 - * may be copied, distributed, and modified under those terms. 18 - * 19 - * This program is distributed in the hope that it will be useful, 20 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 - * GNU General Public License for more details. 23 - * 24 - */ 25 - 26 - #include <linux/clocksource.h> 27 - #include <linux/kernel.h> 28 - #include <linux/of.h> 29 - #include <linux/of_address.h> 30 - #include <linux/of_fdt.h> 31 - #include <linux/of_irq.h> 32 - #include <linux/of_platform.h> 33 - 34 - #include <asm/mach/arch.h> 35 - 36 - #include "board.h" 37 - #include "common.h" 38 - #include "iomap.h" 39 - 40 - static void __init tegra30_dt_init(void) 41 - { 42 - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 43 - } 44 - 45 - static const char *tegra30_dt_board_compat[] = { 46 - "nvidia,tegra30", 47 - NULL 48 - }; 49 - 50 - DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)") 51 - .smp = smp_ops(tegra_smp_ops), 52 - .map_io = tegra_map_common_io, 53 - .init_early = tegra30_init_early, 54 - .init_irq = tegra_dt_init_irq, 55 - .init_time = clocksource_of_init, 56 - .init_machine = tegra30_dt_init, 57 - .init_late = tegra_init_late, 58 - .restart = tegra_assert_system_reset, 59 - .dt_compat = tegra30_dt_board_compat, 60 - MACHINE_END
+6 -1
arch/arm/mach-tegra/board-harmony-pcie.c
··· 62 62 goto err_reg; 63 63 } 64 64 65 - regulator_enable(regulator); 65 + err = regulator_enable(regulator); 66 + if (err) { 67 + pr_err("%s: regulator_enable failed: %d\n", __func__, err); 68 + goto err_en; 69 + } 66 70 67 71 err = tegra_pcie_init(true, true); 68 72 if (err) { ··· 78 74 79 75 err_pcie: 80 76 regulator_disable(regulator); 77 + err_en: 81 78 regulator_put(regulator); 82 79 err_reg: 83 80 gpio_free(en_vdd_1v05);
+1 -3
arch/arm/mach-tegra/board.h
··· 26 26 27 27 void tegra_assert_system_reset(char mode, const char *cmd); 28 28 29 - void __init tegra20_init_early(void); 30 - void __init tegra30_init_early(void); 31 - void __init tegra114_init_early(void); 29 + void __init tegra_init_early(void); 32 30 void __init tegra_map_common_io(void); 33 31 void __init tegra_init_irq(void); 34 32 void __init tegra_dt_init_irq(void);
+6 -25
arch/arm/mach-tegra/common.c
··· 33 33 #include "common.h" 34 34 #include "fuse.h" 35 35 #include "iomap.h" 36 + #include "irq.h" 36 37 #include "pmc.h" 37 38 #include "apbio.h" 38 39 #include "sleep.h" ··· 62 61 void __init tegra_dt_init_irq(void) 63 62 { 64 63 tegra_clocks_init(); 64 + tegra_pmc_init(); 65 65 tegra_init_irq(); 66 66 irqchip_init(); 67 + tegra_legacy_irq_syscore_init(); 67 68 } 68 69 #endif 69 70 ··· 97 94 98 95 } 99 96 100 - static void __init tegra_init_early(void) 97 + void __init tegra_init_early(void) 101 98 { 102 99 tegra_cpu_reset_handler_init(); 103 100 tegra_apb_io_init(); 104 101 tegra_init_fuse(); 105 102 tegra_init_cache(); 106 - tegra_pmc_init(); 107 103 tegra_powergate_init(); 104 + tegra_hotplug_init(); 108 105 } 109 - 110 - #ifdef CONFIG_ARCH_TEGRA_2x_SOC 111 - void __init tegra20_init_early(void) 112 - { 113 - tegra_init_early(); 114 - tegra20_hotplug_init(); 115 - } 116 - #endif 117 - 118 - #ifdef CONFIG_ARCH_TEGRA_3x_SOC 119 - void __init tegra30_init_early(void) 120 - { 121 - tegra_init_early(); 122 - tegra30_hotplug_init(); 123 - } 124 - #endif 125 - 126 - #ifdef CONFIG_ARCH_TEGRA_114_SOC 127 - void __init tegra114_init_early(void) 128 - { 129 - tegra_init_early(); 130 - } 131 - #endif 132 106 133 107 void __init tegra_init_late(void) 134 108 { 109 + tegra_init_suspend(); 135 110 tegra_powergate_debugfs_init(); 136 111 }
+1 -5
arch/arm/mach-tegra/cpuidle-tegra20.c
··· 130 130 struct cpuidle_driver *drv, 131 131 int index) 132 132 { 133 - struct cpuidle_state *state = &drv->states[index]; 134 - u32 cpu_on_time = state->exit_latency; 135 - u32 cpu_off_time = state->target_residency - state->exit_latency; 136 - 137 133 while (tegra20_cpu_is_resettable_soon()) 138 134 cpu_relax(); 139 135 ··· 138 142 139 143 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); 140 144 141 - tegra_idle_lp2_last(cpu_on_time, cpu_off_time); 145 + tegra_idle_lp2_last(); 142 146 143 147 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); 144 148
+1 -9
arch/arm/mach-tegra/cpuidle-tegra30.c
··· 72 72 struct cpuidle_driver *drv, 73 73 int index) 74 74 { 75 - struct cpuidle_state *state = &drv->states[index]; 76 - u32 cpu_on_time = state->exit_latency; 77 - u32 cpu_off_time = state->target_residency - state->exit_latency; 78 - 79 75 /* All CPUs entering LP2 is not working. 80 76 * Don't let CPU0 enter LP2 when any secondary CPU is online. 81 77 */ ··· 82 86 83 87 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); 84 88 85 - tegra_idle_lp2_last(cpu_on_time, cpu_off_time); 89 + tegra_idle_lp2_last(); 86 90 87 91 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); 88 92 ··· 98 102 99 103 smp_wmb(); 100 104 101 - save_cpu_arch_register(); 102 - 103 105 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); 104 - 105 - restore_cpu_arch_register(); 106 106 107 107 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); 108 108
+4
arch/arm/mach-tegra/fuse.c
··· 2 2 * arch/arm/mach-tegra/fuse.c 3 3 * 4 4 * Copyright (C) 2010 Google, Inc. 5 + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. 5 6 * 6 7 * Author: 7 8 * Colin Cross <ccross@android.com> ··· 137 136 case TEGRA30: 138 137 tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT; 139 138 tegra_init_speedo_data = &tegra30_init_speedo_data; 139 + break; 140 + case TEGRA114: 141 + tegra_init_speedo_data = &tegra114_init_speedo_data; 140 142 break; 141 143 default: 142 144 pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
+7
arch/arm/mach-tegra/fuse.h
··· 1 1 /* 2 2 * Copyright (C) 2010 Google, Inc. 3 + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. 3 4 * 4 5 * Author: 5 6 * Colin Cross <ccross@android.com> ··· 65 64 void tegra30_init_speedo_data(void); 66 65 #else 67 66 static inline void tegra30_init_speedo_data(void) {} 67 + #endif 68 + 69 + #ifdef CONFIG_ARCH_TEGRA_114_SOC 70 + void tegra114_init_speedo_data(void); 71 + #else 72 + static inline void tegra114_init_speedo_data(void) {} 68 73 #endif 69 74 70 75 #endif
-3
arch/arm/mach-tegra/headsmp.S
··· 7 7 8 8 ENTRY(tegra_secondary_startup) 9 9 bl v7_invalidate_l1 10 - /* Enable coresight */ 11 - mov32 r0, 0xC5ACCE55 12 - mcr p14, 0, r0, c7, c12, 6 13 10 b secondary_startup 14 11 ENDPROC(tegra_secondary_startup)
+9 -14
arch/arm/mach-tegra/hotplug.c
··· 1 1 /* 2 - * 3 2 * Copyright (C) 2002 ARM Ltd. 4 3 * All Rights Reserved 5 - * Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved. 4 + * Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved. 6 5 * 7 6 * This program is free software; you can redistribute it and/or modify 8 7 * it under the terms of the GNU General Public License version 2 as ··· 14 15 #include <asm/cacheflush.h> 15 16 #include <asm/smp_plat.h> 16 17 18 + #include "fuse.h" 17 19 #include "sleep.h" 18 20 19 21 static void (*tegra_hotplug_shutdown)(void); ··· 56 56 return cpu == 0 ? -EPERM : 0; 57 57 } 58 58 59 - #ifdef CONFIG_ARCH_TEGRA_2x_SOC 60 - extern void tegra20_hotplug_shutdown(void); 61 - void __init tegra20_hotplug_init(void) 59 + void __init tegra_hotplug_init(void) 62 60 { 63 - tegra_hotplug_shutdown = tegra20_hotplug_shutdown; 64 - } 65 - #endif 61 + if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) 62 + return; 66 63 67 - #ifdef CONFIG_ARCH_TEGRA_3x_SOC 68 - extern void tegra30_hotplug_shutdown(void); 69 - void __init tegra30_hotplug_init(void) 70 - { 71 - tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 64 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) 65 + tegra_hotplug_shutdown = tegra20_hotplug_shutdown; 66 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 67 + tegra_hotplug_shutdown = tegra30_hotplug_shutdown; 72 68 } 73 - #endif
+95 -1
arch/arm/mach-tegra/irq.c
··· 4 4 * Author: 5 5 * Colin Cross <ccross@android.com> 6 6 * 7 - * Copyright (C) 2010, NVIDIA Corporation 7 + * Copyright (C) 2010,2013, NVIDIA Corporation 8 8 * 9 9 * This software is licensed under the terms of the GNU General Public 10 10 * License version 2, as published by the Free Software Foundation, and ··· 23 23 #include <linux/io.h> 24 24 #include <linux/of.h> 25 25 #include <linux/irqchip/arm-gic.h> 26 + #include <linux/syscore_ops.h> 26 27 27 28 #include "board.h" 28 29 #include "iomap.h" ··· 44 43 #define ICTLR_COP_IEP_CLASS 0x3c 45 44 46 45 #define FIRST_LEGACY_IRQ 32 46 + #define TEGRA_MAX_NUM_ICTLRS 5 47 47 48 48 #define SGI_MASK 0xFFFF 49 49 ··· 57 55 IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), 58 56 IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), 59 57 }; 58 + 59 + #ifdef CONFIG_PM_SLEEP 60 + static u32 cop_ier[TEGRA_MAX_NUM_ICTLRS]; 61 + static u32 cop_iep[TEGRA_MAX_NUM_ICTLRS]; 62 + static u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS]; 63 + static u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS]; 64 + 65 + static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS]; 66 + #endif 60 67 61 68 bool tegra_pending_sgi(void) 62 69 { ··· 136 125 return 1; 137 126 } 138 127 128 + #ifdef CONFIG_PM_SLEEP 129 + static int tegra_set_wake(struct irq_data *d, unsigned int enable) 130 + { 131 + u32 irq = d->irq; 132 + u32 index, mask; 133 + 134 + if (irq < FIRST_LEGACY_IRQ || 135 + irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32) 136 + return -EINVAL; 137 + 138 + index = ((irq - FIRST_LEGACY_IRQ) / 32); 139 + mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); 140 + if (enable) 141 + ictlr_wake_mask[index] |= mask; 142 + else 143 + ictlr_wake_mask[index] &= ~mask; 144 + 145 + return 0; 146 + } 147 + 148 + static int tegra_legacy_irq_suspend(void) 149 + { 150 + unsigned long flags; 151 + int i; 152 + 153 + local_irq_save(flags); 154 + for (i = 0; i < num_ictlrs; i++) { 155 + void __iomem *ictlr = ictlr_reg_base[i]; 156 + /* Save interrupt state */ 157 + cpu_ier[i] = readl_relaxed(ictlr + ICTLR_CPU_IER); 158 + cpu_iep[i] = readl_relaxed(ictlr + ICTLR_CPU_IEP_CLASS); 159 + cop_ier[i] = readl_relaxed(ictlr + ICTLR_COP_IER); 160 + cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS); 161 + 162 + /* Disable COP interrupts */ 163 + writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR); 164 + 165 + /* Disable CPU interrupts */ 166 + writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR); 167 + 168 + /* Enable the wakeup sources of ictlr */ 169 + writel_relaxed(ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET); 170 + } 171 + local_irq_restore(flags); 172 + 173 + return 0; 174 + } 175 + 176 + static void tegra_legacy_irq_resume(void) 177 + { 178 + unsigned long flags; 179 + int i; 180 + 181 + local_irq_save(flags); 182 + for (i = 0; i < num_ictlrs; i++) { 183 + void __iomem *ictlr = ictlr_reg_base[i]; 184 + writel_relaxed(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS); 185 + writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR); 186 + writel_relaxed(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET); 187 + writel_relaxed(cop_iep[i], ictlr + ICTLR_COP_IEP_CLASS); 188 + writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR); 189 + writel_relaxed(cop_ier[i], ictlr + ICTLR_COP_IER_SET); 190 + } 191 + local_irq_restore(flags); 192 + } 193 + 194 + static struct syscore_ops tegra_legacy_irq_syscore_ops = { 195 + .suspend = tegra_legacy_irq_suspend, 196 + .resume = tegra_legacy_irq_resume, 197 + }; 198 + 199 + int tegra_legacy_irq_syscore_init(void) 200 + { 201 + register_syscore_ops(&tegra_legacy_irq_syscore_ops); 202 + 203 + return 0; 204 + } 205 + #else 206 + #define tegra_set_wake NULL 207 + #endif 208 + 139 209 void __init tegra_init_irq(void) 140 210 { 141 211 int i; ··· 242 150 gic_arch_extn.irq_mask = tegra_mask; 243 151 gic_arch_extn.irq_unmask = tegra_unmask; 244 152 gic_arch_extn.irq_retrigger = tegra_retrigger; 153 + gic_arch_extn.irq_set_wake = tegra_set_wake; 154 + gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND; 245 155 246 156 /* 247 157 * Check if there is a devicetree present, since the GIC will be
+6
arch/arm/mach-tegra/irq.h
··· 19 19 20 20 bool tegra_pending_sgi(void); 21 21 22 + #ifdef CONFIG_PM_SLEEP 23 + int tegra_legacy_irq_syscore_init(void); 24 + #else 25 + static inline int tegra_legacy_irq_syscore_init(void) { return 0; } 26 + #endif 27 + 22 28 #endif
+54 -65
arch/arm/mach-tegra/platsmp.c
··· 26 26 #include <asm/smp_scu.h> 27 27 #include <asm/smp_plat.h> 28 28 29 - #include <mach/powergate.h> 30 - 31 29 #include "fuse.h" 32 30 #include "flowctrl.h" 33 31 #include "reset.h" 32 + #include "pmc.h" 34 33 35 34 #include "common.h" 36 35 #include "iomap.h" 37 36 38 - extern void tegra_secondary_startup(void); 39 - 40 37 static cpumask_t tegra_cpu_init_mask; 41 - 42 - #define EVP_CPU_RESET_VECTOR \ 43 - (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) 44 38 45 39 static void __cpuinit tegra_secondary_init(unsigned int cpu) 46 40 { ··· 48 54 cpumask_set_cpu(cpu, &tegra_cpu_init_mask); 49 55 } 50 56 51 - static int tegra20_power_up_cpu(unsigned int cpu) 57 + 58 + static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle) 52 59 { 53 - /* Enable the CPU clock. */ 60 + cpu = cpu_logical_map(cpu); 61 + 62 + /* 63 + * Force the CPU into reset. The CPU must remain in reset when 64 + * the flow controller state is cleared (which will cause the 65 + * flow controller to stop driving reset if the CPU has been 66 + * power-gated via the flow controller). This will have no 67 + * effect on first boot of the CPU since it should already be 68 + * in reset. 69 + */ 70 + tegra_put_cpu_in_reset(cpu); 71 + 72 + /* 73 + * Unhalt the CPU. If the flow controller was used to 74 + * power-gate the CPU this will cause the flow controller to 75 + * stop driving reset. The CPU will remain in reset because the 76 + * clock and reset block is now driving reset. 77 + */ 78 + flowctrl_write_cpu_halt(cpu, 0); 79 + 54 80 tegra_enable_cpu_clock(cpu); 55 - 56 - /* Clear flow controller CSR. */ 57 - flowctrl_write_cpu_csr(cpu, 0); 58 - 81 + flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ 82 + tegra_cpu_out_of_reset(cpu); 59 83 return 0; 60 84 } 61 85 62 - static int tegra30_power_up_cpu(unsigned int cpu) 86 + static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle) 63 87 { 64 - int ret, pwrgateid; 88 + int ret; 65 89 unsigned long timeout; 66 90 67 - pwrgateid = tegra_cpu_powergate_id(cpu); 68 - if (pwrgateid < 0) 69 - return pwrgateid; 91 + cpu = cpu_logical_map(cpu); 92 + tegra_put_cpu_in_reset(cpu); 93 + flowctrl_write_cpu_halt(cpu, 0); 70 94 71 95 /* 72 96 * The power up sequence of cold boot CPU and warm boot CPU ··· 97 85 * the IO clamps. 98 86 * For cold boot CPU, do not wait. After the cold boot CPU be 99 87 * booted, it will run to tegra_secondary_init() and set 100 - * tegra_cpu_init_mask which influences what tegra30_power_up_cpu() 88 + * tegra_cpu_init_mask which influences what tegra30_boot_secondary() 101 89 * next time around. 102 90 */ 103 91 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { 104 92 timeout = jiffies + msecs_to_jiffies(50); 105 93 do { 106 - if (!tegra_powergate_is_powered(pwrgateid)) 94 + if (tegra_pmc_cpu_is_powered(cpu)) 107 95 goto remove_clamps; 108 96 udelay(10); 109 97 } while (time_before(jiffies, timeout)); ··· 115 103 * be un-gated by un-toggling the power gate register 116 104 * manually. 117 105 */ 118 - if (!tegra_powergate_is_powered(pwrgateid)) { 119 - ret = tegra_powergate_power_on(pwrgateid); 106 + if (!tegra_pmc_cpu_is_powered(cpu)) { 107 + ret = tegra_pmc_cpu_power_on(cpu); 120 108 if (ret) 121 109 return ret; 122 110 123 111 /* Wait for the power to come up. */ 124 112 timeout = jiffies + msecs_to_jiffies(100); 125 - while (tegra_powergate_is_powered(pwrgateid)) { 113 + while (tegra_pmc_cpu_is_powered(cpu)) { 126 114 if (time_after(jiffies, timeout)) 127 115 return -ETIMEDOUT; 128 116 udelay(10); ··· 135 123 udelay(10); 136 124 137 125 /* Remove I/O clamps. */ 138 - ret = tegra_powergate_remove_clamping(pwrgateid); 126 + ret = tegra_pmc_cpu_remove_clamping(cpu); 127 + if (ret) 128 + return ret; 129 + 139 130 udelay(10); 140 131 141 - /* Clear flow controller CSR. */ 142 - flowctrl_write_cpu_csr(cpu, 0); 143 - 132 + flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ 133 + tegra_cpu_out_of_reset(cpu); 144 134 return 0; 145 135 } 146 136 147 - static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle) 137 + static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle) 148 138 { 149 - int status; 150 - 151 139 cpu = cpu_logical_map(cpu); 140 + return tegra_pmc_cpu_power_on(cpu); 141 + } 152 142 153 - /* 154 - * Force the CPU into reset. The CPU must remain in reset when the 155 - * flow controller state is cleared (which will cause the flow 156 - * controller to stop driving reset if the CPU has been power-gated 157 - * via the flow controller). This will have no effect on first boot 158 - * of the CPU since it should already be in reset. 159 - */ 160 - tegra_put_cpu_in_reset(cpu); 143 + static int __cpuinit tegra_boot_secondary(unsigned int cpu, 144 + struct task_struct *idle) 145 + { 146 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) 147 + return tegra20_boot_secondary(cpu, idle); 148 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 149 + return tegra30_boot_secondary(cpu, idle); 150 + if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) 151 + return tegra114_boot_secondary(cpu, idle); 161 152 162 - /* 163 - * Unhalt the CPU. If the flow controller was used to power-gate the 164 - * CPU this will cause the flow controller to stop driving reset. 165 - * The CPU will remain in reset because the clock and reset block 166 - * is now driving reset. 167 - */ 168 - flowctrl_write_cpu_halt(cpu, 0); 169 - 170 - switch (tegra_chip_id) { 171 - case TEGRA20: 172 - status = tegra20_power_up_cpu(cpu); 173 - break; 174 - case TEGRA30: 175 - status = tegra30_power_up_cpu(cpu); 176 - break; 177 - default: 178 - status = -EINVAL; 179 - break; 180 - } 181 - 182 - if (status) 183 - goto done; 184 - 185 - /* Take the CPU out of reset. */ 186 - tegra_cpu_out_of_reset(cpu); 187 - done: 188 - return status; 153 + return -EINVAL; 189 154 } 190 155 191 156 static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
+81 -69
arch/arm/mach-tegra/pm.c
··· 22 22 #include <linux/cpumask.h> 23 23 #include <linux/delay.h> 24 24 #include <linux/cpu_pm.h> 25 - #include <linux/clk.h> 25 + #include <linux/suspend.h> 26 26 #include <linux/err.h> 27 27 #include <linux/clk/tegra.h> 28 28 ··· 37 37 #include "reset.h" 38 38 #include "flowctrl.h" 39 39 #include "fuse.h" 40 + #include "pmc.h" 40 41 #include "sleep.h" 41 42 42 - #define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */ 43 - 44 - #define PMC_CTRL 0x0 45 - #define PMC_CPUPWRGOOD_TIMER 0xc8 46 - #define PMC_CPUPWROFF_TIMER 0xcc 47 - 48 43 #ifdef CONFIG_PM_SLEEP 49 - static unsigned int g_diag_reg; 50 44 static DEFINE_SPINLOCK(tegra_lp2_lock); 51 - static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); 52 - static struct clk *tegra_pclk; 53 45 void (*tegra_tear_down_cpu)(void); 54 - 55 - void save_cpu_arch_register(void) 56 - { 57 - /* read diagnostic register */ 58 - asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc"); 59 - return; 60 - } 61 - 62 - void restore_cpu_arch_register(void) 63 - { 64 - /* write diagnostic register */ 65 - asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc"); 66 - return; 67 - } 68 - 69 - static void set_power_timers(unsigned long us_on, unsigned long us_off) 70 - { 71 - unsigned long long ticks; 72 - unsigned long long pclk; 73 - unsigned long rate; 74 - static unsigned long tegra_last_pclk; 75 - 76 - if (tegra_pclk == NULL) { 77 - tegra_pclk = clk_get_sys(NULL, "pclk"); 78 - WARN_ON(IS_ERR(tegra_pclk)); 79 - } 80 - 81 - rate = clk_get_rate(tegra_pclk); 82 - 83 - if (WARN_ON_ONCE(rate <= 0)) 84 - pclk = 100000000; 85 - else 86 - pclk = rate; 87 - 88 - if ((rate != tegra_last_pclk)) { 89 - ticks = (us_on * pclk) + 999999ull; 90 - do_div(ticks, 1000000); 91 - writel((unsigned long)ticks, pmc + PMC_CPUPWRGOOD_TIMER); 92 - 93 - ticks = (us_off * pclk) + 999999ull; 94 - do_div(ticks, 1000000); 95 - writel((unsigned long)ticks, pmc + PMC_CPUPWROFF_TIMER); 96 - wmb(); 97 - } 98 - tegra_last_pclk = pclk; 99 - } 100 46 101 47 /* 102 48 * restore_cpu_complex ··· 65 119 tegra_cpu_clock_resume(); 66 120 67 121 flowctrl_cpu_suspend_exit(cpu); 68 - 69 - restore_cpu_arch_register(); 70 122 } 71 123 72 124 /* ··· 89 145 tegra_cpu_clock_suspend(); 90 146 91 147 flowctrl_cpu_suspend_enter(cpu); 92 - 93 - save_cpu_arch_register(); 94 148 } 95 149 96 150 void tegra_clear_cpu_in_lp2(int phy_cpu_id) ··· 139 197 return 0; 140 198 } 141 199 142 - void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time) 200 + void tegra_idle_lp2_last(void) 143 201 { 144 - u32 mode; 145 - 146 - /* Only the last cpu down does the final suspend steps */ 147 - mode = readl(pmc + PMC_CTRL); 148 - mode |= TEGRA_POWER_CPU_PWRREQ_OE; 149 - writel(mode, pmc + PMC_CTRL); 150 - 151 - set_power_timers(cpu_on_time, cpu_off_time); 202 + tegra_pmc_pm_set(TEGRA_SUSPEND_LP2); 152 203 153 204 cpu_cluster_pm_enter(); 154 205 suspend_cpu_complex(); ··· 150 215 151 216 restore_cpu_complex(); 152 217 cpu_cluster_pm_exit(); 218 + } 219 + 220 + enum tegra_suspend_mode tegra_pm_validate_suspend_mode( 221 + enum tegra_suspend_mode mode) 222 + { 223 + /* Tegra114 didn't support any suspending mode yet. */ 224 + if (tegra_chip_id == TEGRA114) 225 + return TEGRA_SUSPEND_NONE; 226 + 227 + /* 228 + * The Tegra devices only support suspending to LP2 currently. 229 + */ 230 + if (mode > TEGRA_SUSPEND_LP2) 231 + return TEGRA_SUSPEND_LP2; 232 + 233 + return mode; 234 + } 235 + 236 + static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = { 237 + [TEGRA_SUSPEND_NONE] = "none", 238 + [TEGRA_SUSPEND_LP2] = "LP2", 239 + [TEGRA_SUSPEND_LP1] = "LP1", 240 + [TEGRA_SUSPEND_LP0] = "LP0", 241 + }; 242 + 243 + static int __cpuinit tegra_suspend_enter(suspend_state_t state) 244 + { 245 + enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode(); 246 + 247 + if (WARN_ON(mode < TEGRA_SUSPEND_NONE || 248 + mode >= TEGRA_MAX_SUSPEND_MODE)) 249 + return -EINVAL; 250 + 251 + pr_info("Entering suspend state %s\n", lp_state[mode]); 252 + 253 + tegra_pmc_pm_set(mode); 254 + 255 + local_fiq_disable(); 256 + 257 + suspend_cpu_complex(); 258 + switch (mode) { 259 + case TEGRA_SUSPEND_LP2: 260 + tegra_set_cpu_in_lp2(0); 261 + break; 262 + default: 263 + break; 264 + } 265 + 266 + cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu); 267 + 268 + switch (mode) { 269 + case TEGRA_SUSPEND_LP2: 270 + tegra_clear_cpu_in_lp2(0); 271 + break; 272 + default: 273 + break; 274 + } 275 + restore_cpu_complex(); 276 + 277 + local_fiq_enable(); 278 + 279 + return 0; 280 + } 281 + 282 + static const struct platform_suspend_ops tegra_suspend_ops = { 283 + .valid = suspend_valid_only_mem, 284 + .enter = tegra_suspend_enter, 285 + }; 286 + 287 + void __init tegra_init_suspend(void) 288 + { 289 + if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NONE) 290 + return; 291 + 292 + tegra_pmc_suspend_init(); 293 + 294 + suspend_set_ops(&tegra_suspend_ops); 153 295 } 154 296 #endif
+16 -1
arch/arm/mach-tegra/pm.h
··· 21 21 #ifndef _MACH_TEGRA_PM_H_ 22 22 #define _MACH_TEGRA_PM_H_ 23 23 24 + #include "pmc.h" 25 + 24 26 extern unsigned long l2x0_saved_regs_addr; 25 27 26 28 void save_cpu_arch_register(void); ··· 31 29 void tegra_clear_cpu_in_lp2(int phy_cpu_id); 32 30 bool tegra_set_cpu_in_lp2(int phy_cpu_id); 33 31 34 - void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time); 32 + void tegra_idle_lp2_last(void); 35 33 extern void (*tegra_tear_down_cpu)(void); 34 + 35 + #ifdef CONFIG_PM_SLEEP 36 + enum tegra_suspend_mode tegra_pm_validate_suspend_mode( 37 + enum tegra_suspend_mode mode); 38 + void tegra_init_suspend(void); 39 + #else 40 + enum tegra_suspend_mode tegra_pm_validate_suspend_mode( 41 + enum tegra_suspend_mode mode) 42 + { 43 + return TEGRA_SUSPEND_NONE; 44 + } 45 + static inline void tegra_init_suspend(void) {} 46 + #endif 36 47 37 48 #endif /* _MACH_TEGRA_PM_H_ */
+284 -30
arch/arm/mach-tegra/pmc.c
··· 1 1 /* 2 - * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. 2 + * Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved. 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify it 5 5 * under the terms and conditions of the GNU General Public License, ··· 16 16 */ 17 17 18 18 #include <linux/kernel.h> 19 + #include <linux/clk.h> 19 20 #include <linux/io.h> 20 21 #include <linux/of.h> 22 + #include <linux/of_address.h> 21 23 22 - #include "iomap.h" 24 + #include "fuse.h" 25 + #include "pm.h" 26 + #include "pmc.h" 27 + #include "sleep.h" 23 28 24 - #define PMC_CTRL 0x0 25 - #define PMC_CTRL_INTR_LOW (1 << 17) 29 + #define TEGRA_POWER_EFFECT_LP0 (1 << 14) /* LP0 when CPU pwr gated */ 30 + #define TEGRA_POWER_CPU_PWRREQ_POLARITY (1 << 15) /* CPU pwr req polarity */ 31 + #define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */ 32 + 33 + #define PMC_CTRL 0x0 34 + #define PMC_CTRL_INTR_LOW (1 << 17) 35 + #define PMC_PWRGATE_TOGGLE 0x30 36 + #define PMC_PWRGATE_TOGGLE_START (1 << 8) 37 + #define PMC_REMOVE_CLAMPING 0x34 38 + #define PMC_PWRGATE_STATUS 0x38 39 + 40 + #define PMC_CPUPWRGOOD_TIMER 0xc8 41 + #define PMC_CPUPWROFF_TIMER 0xcc 42 + 43 + #define TEGRA_POWERGATE_PCIE 3 44 + #define TEGRA_POWERGATE_VDEC 4 45 + #define TEGRA_POWERGATE_CPU1 9 46 + #define TEGRA_POWERGATE_CPU2 10 47 + #define TEGRA_POWERGATE_CPU3 11 48 + 49 + static u8 tegra_cpu_domains[] = { 50 + 0xFF, /* not available for CPU0 */ 51 + TEGRA_POWERGATE_CPU1, 52 + TEGRA_POWERGATE_CPU2, 53 + TEGRA_POWERGATE_CPU3, 54 + }; 55 + static DEFINE_SPINLOCK(tegra_powergate_lock); 56 + 57 + static void __iomem *tegra_pmc_base; 58 + static bool tegra_pmc_invert_interrupt; 59 + static struct clk *tegra_pclk; 60 + 61 + struct pmc_pm_data { 62 + u32 cpu_good_time; /* CPU power good time in uS */ 63 + u32 cpu_off_time; /* CPU power off time in uS */ 64 + u32 core_osc_time; /* Core power good osc time in uS */ 65 + u32 core_pmu_time; /* Core power good pmu time in uS */ 66 + u32 core_off_time; /* Core power off time in uS */ 67 + bool corereq_high; /* Core power request active-high */ 68 + bool sysclkreq_high; /* System clock request active-high */ 69 + bool combined_req; /* Combined pwr req for CPU & Core */ 70 + bool cpu_pwr_good_en; /* CPU power good signal is enabled */ 71 + u32 lp0_vec_phy_addr; /* The phy addr of LP0 warm boot code */ 72 + u32 lp0_vec_size; /* The size of LP0 warm boot code */ 73 + enum tegra_suspend_mode suspend_mode; 74 + }; 75 + static struct pmc_pm_data pmc_pm_data; 26 76 27 77 static inline u32 tegra_pmc_readl(u32 reg) 28 78 { 29 - return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg)); 79 + return readl(tegra_pmc_base + reg); 30 80 } 31 81 32 82 static inline void tegra_pmc_writel(u32 val, u32 reg) 33 83 { 34 - writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg)); 84 + writel(val, tegra_pmc_base + reg); 35 85 } 36 86 37 - #ifdef CONFIG_OF 87 + static int tegra_pmc_get_cpu_powerdomain_id(int cpuid) 88 + { 89 + if (cpuid <= 0 || cpuid >= num_possible_cpus()) 90 + return -EINVAL; 91 + return tegra_cpu_domains[cpuid]; 92 + } 93 + 94 + static bool tegra_pmc_powergate_is_powered(int id) 95 + { 96 + return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1; 97 + } 98 + 99 + static int tegra_pmc_powergate_set(int id, bool new_state) 100 + { 101 + bool old_state; 102 + unsigned long flags; 103 + 104 + spin_lock_irqsave(&tegra_powergate_lock, flags); 105 + 106 + old_state = tegra_pmc_powergate_is_powered(id); 107 + WARN_ON(old_state == new_state); 108 + 109 + tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE); 110 + 111 + spin_unlock_irqrestore(&tegra_powergate_lock, flags); 112 + 113 + return 0; 114 + } 115 + 116 + static int tegra_pmc_powergate_remove_clamping(int id) 117 + { 118 + u32 mask; 119 + 120 + /* 121 + * Tegra has a bug where PCIE and VDE clamping masks are 122 + * swapped relatively to the partition ids. 123 + */ 124 + if (id == TEGRA_POWERGATE_VDEC) 125 + mask = (1 << TEGRA_POWERGATE_PCIE); 126 + else if (id == TEGRA_POWERGATE_PCIE) 127 + mask = (1 << TEGRA_POWERGATE_VDEC); 128 + else 129 + mask = (1 << id); 130 + 131 + tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING); 132 + 133 + return 0; 134 + } 135 + 136 + bool tegra_pmc_cpu_is_powered(int cpuid) 137 + { 138 + int id; 139 + 140 + id = tegra_pmc_get_cpu_powerdomain_id(cpuid); 141 + if (id < 0) 142 + return false; 143 + return tegra_pmc_powergate_is_powered(id); 144 + } 145 + 146 + int tegra_pmc_cpu_power_on(int cpuid) 147 + { 148 + int id; 149 + 150 + id = tegra_pmc_get_cpu_powerdomain_id(cpuid); 151 + if (id < 0) 152 + return id; 153 + return tegra_pmc_powergate_set(id, true); 154 + } 155 + 156 + int tegra_pmc_cpu_remove_clamping(int cpuid) 157 + { 158 + int id; 159 + 160 + id = tegra_pmc_get_cpu_powerdomain_id(cpuid); 161 + if (id < 0) 162 + return id; 163 + return tegra_pmc_powergate_remove_clamping(id); 164 + } 165 + 166 + #ifdef CONFIG_PM_SLEEP 167 + static void set_power_timers(u32 us_on, u32 us_off, unsigned long rate) 168 + { 169 + unsigned long long ticks; 170 + unsigned long long pclk; 171 + static unsigned long tegra_last_pclk; 172 + 173 + if (WARN_ON_ONCE(rate <= 0)) 174 + pclk = 100000000; 175 + else 176 + pclk = rate; 177 + 178 + if ((rate != tegra_last_pclk)) { 179 + ticks = (us_on * pclk) + 999999ull; 180 + do_div(ticks, 1000000); 181 + tegra_pmc_writel((unsigned long)ticks, PMC_CPUPWRGOOD_TIMER); 182 + 183 + ticks = (us_off * pclk) + 999999ull; 184 + do_div(ticks, 1000000); 185 + tegra_pmc_writel((unsigned long)ticks, PMC_CPUPWROFF_TIMER); 186 + wmb(); 187 + } 188 + tegra_last_pclk = pclk; 189 + } 190 + 191 + enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void) 192 + { 193 + return pmc_pm_data.suspend_mode; 194 + } 195 + 196 + void tegra_pmc_pm_set(enum tegra_suspend_mode mode) 197 + { 198 + u32 reg; 199 + unsigned long rate = 0; 200 + 201 + reg = tegra_pmc_readl(PMC_CTRL); 202 + reg |= TEGRA_POWER_CPU_PWRREQ_OE; 203 + reg &= ~TEGRA_POWER_EFFECT_LP0; 204 + 205 + switch (mode) { 206 + case TEGRA_SUSPEND_LP2: 207 + rate = clk_get_rate(tegra_pclk); 208 + break; 209 + default: 210 + break; 211 + } 212 + 213 + set_power_timers(pmc_pm_data.cpu_good_time, pmc_pm_data.cpu_off_time, 214 + rate); 215 + 216 + tegra_pmc_writel(reg, PMC_CTRL); 217 + } 218 + 219 + void tegra_pmc_suspend_init(void) 220 + { 221 + u32 reg; 222 + 223 + /* Always enable CPU power request */ 224 + reg = tegra_pmc_readl(PMC_CTRL); 225 + reg |= TEGRA_POWER_CPU_PWRREQ_OE; 226 + tegra_pmc_writel(reg, PMC_CTRL); 227 + } 228 + #endif 229 + 38 230 static const struct of_device_id matches[] __initconst = { 231 + { .compatible = "nvidia,tegra114-pmc" }, 232 + { .compatible = "nvidia,tegra30-pmc" }, 39 233 { .compatible = "nvidia,tegra20-pmc" }, 40 234 { } 41 235 }; 42 - #endif 236 + 237 + static void tegra_pmc_parse_dt(void) 238 + { 239 + struct device_node *np; 240 + u32 prop; 241 + enum tegra_suspend_mode suspend_mode; 242 + u32 core_good_time[2] = {0, 0}; 243 + u32 lp0_vec[2] = {0, 0}; 244 + 245 + np = of_find_matching_node(NULL, matches); 246 + BUG_ON(!np); 247 + 248 + tegra_pmc_base = of_iomap(np, 0); 249 + 250 + tegra_pmc_invert_interrupt = of_property_read_bool(np, 251 + "nvidia,invert-interrupt"); 252 + tegra_pclk = of_clk_get_by_name(np, "pclk"); 253 + WARN_ON(IS_ERR(tegra_pclk)); 254 + 255 + /* Grabbing the power management configurations */ 256 + if (of_property_read_u32(np, "nvidia,suspend-mode", &prop)) { 257 + suspend_mode = TEGRA_SUSPEND_NONE; 258 + } else { 259 + switch (prop) { 260 + case 0: 261 + suspend_mode = TEGRA_SUSPEND_LP0; 262 + break; 263 + case 1: 264 + suspend_mode = TEGRA_SUSPEND_LP1; 265 + break; 266 + case 2: 267 + suspend_mode = TEGRA_SUSPEND_LP2; 268 + break; 269 + default: 270 + suspend_mode = TEGRA_SUSPEND_NONE; 271 + break; 272 + } 273 + } 274 + suspend_mode = tegra_pm_validate_suspend_mode(suspend_mode); 275 + 276 + if (of_property_read_u32(np, "nvidia,cpu-pwr-good-time", &prop)) 277 + suspend_mode = TEGRA_SUSPEND_NONE; 278 + pmc_pm_data.cpu_good_time = prop; 279 + 280 + if (of_property_read_u32(np, "nvidia,cpu-pwr-off-time", &prop)) 281 + suspend_mode = TEGRA_SUSPEND_NONE; 282 + pmc_pm_data.cpu_off_time = prop; 283 + 284 + if (of_property_read_u32_array(np, "nvidia,core-pwr-good-time", 285 + core_good_time, ARRAY_SIZE(core_good_time))) 286 + suspend_mode = TEGRA_SUSPEND_NONE; 287 + pmc_pm_data.core_osc_time = core_good_time[0]; 288 + pmc_pm_data.core_pmu_time = core_good_time[1]; 289 + 290 + if (of_property_read_u32(np, "nvidia,core-pwr-off-time", 291 + &prop)) 292 + suspend_mode = TEGRA_SUSPEND_NONE; 293 + pmc_pm_data.core_off_time = prop; 294 + 295 + pmc_pm_data.corereq_high = of_property_read_bool(np, 296 + "nvidia,core-power-req-active-high"); 297 + 298 + pmc_pm_data.sysclkreq_high = of_property_read_bool(np, 299 + "nvidia,sys-clock-req-active-high"); 300 + 301 + pmc_pm_data.combined_req = of_property_read_bool(np, 302 + "nvidia,combined-power-req"); 303 + 304 + pmc_pm_data.cpu_pwr_good_en = of_property_read_bool(np, 305 + "nvidia,cpu-pwr-good-en"); 306 + 307 + if (of_property_read_u32_array(np, "nvidia,lp0-vec", lp0_vec, 308 + ARRAY_SIZE(lp0_vec))) 309 + if (suspend_mode == TEGRA_SUSPEND_LP0) 310 + suspend_mode = TEGRA_SUSPEND_LP1; 311 + 312 + pmc_pm_data.lp0_vec_phy_addr = lp0_vec[0]; 313 + pmc_pm_data.lp0_vec_size = lp0_vec[1]; 314 + 315 + pmc_pm_data.suspend_mode = suspend_mode; 316 + } 43 317 44 318 void __init tegra_pmc_init(void) 45 319 { 46 - /* 47 - * For now, Harmony is the only board that uses the PMC, and it wants 48 - * the signal inverted. Seaboard would too if it used the PMC. 49 - * Hopefully by the time other boards want to use the PMC, everything 50 - * will be device-tree, or they also want it inverted. 51 - */ 52 - bool invert_interrupt = true; 53 320 u32 val; 54 321 55 - #ifdef CONFIG_OF 56 - if (of_have_populated_dt()) { 57 - struct device_node *np; 58 - 59 - invert_interrupt = false; 60 - 61 - np = of_find_matching_node(NULL, matches); 62 - if (np) { 63 - if (of_find_property(np, "nvidia,invert-interrupt", 64 - NULL)) 65 - invert_interrupt = true; 66 - } 67 - } 68 - #endif 322 + tegra_pmc_parse_dt(); 69 323 70 324 val = tegra_pmc_readl(PMC_CTRL); 71 - if (invert_interrupt) 325 + if (tegra_pmc_invert_interrupt) 72 326 val |= PMC_CTRL_INTR_LOW; 73 327 else 74 328 val &= ~PMC_CTRL_INTR_LOW;
+18
arch/arm/mach-tegra/pmc.h
··· 18 18 #ifndef __MACH_TEGRA_PMC_H 19 19 #define __MACH_TEGRA_PMC_H 20 20 21 + enum tegra_suspend_mode { 22 + TEGRA_SUSPEND_NONE = 0, 23 + TEGRA_SUSPEND_LP2, /* CPU voltage off */ 24 + TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */ 25 + TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */ 26 + TEGRA_MAX_SUSPEND_MODE, 27 + }; 28 + 29 + #ifdef CONFIG_PM_SLEEP 30 + enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void); 31 + void tegra_pmc_pm_set(enum tegra_suspend_mode mode); 32 + void tegra_pmc_suspend_init(void); 33 + #endif 34 + 35 + bool tegra_pmc_cpu_is_powered(int cpuid); 36 + int tegra_pmc_cpu_power_on(int cpuid); 37 + int tegra_pmc_cpu_remove_clamping(int cpuid); 38 + 21 39 void tegra_pmc_init(void); 22 40 23 41 #endif
+39 -9
arch/arm/mach-tegra/reset-handler.S
··· 41 41 */ 42 42 ENTRY(tegra_resume) 43 43 bl v7_invalidate_l1 44 - /* Enable coresight */ 45 - mov32 r0, 0xC5ACCE55 46 - mcr p14, 0, r0, c7, c12, 6 47 44 48 45 cpu_id r0 49 46 cmp r0, #0 @ CPU0? ··· 96 99 * 97 100 * Register usage within the reset handler: 98 101 * 102 + * Others: scratch 103 + * R6 = SoC ID << 8 99 104 * R7 = CPU present (to the OS) mask 100 105 * R8 = CPU in LP1 state mask 101 106 * R9 = CPU in LP2 state mask ··· 113 114 ENTRY(__tegra_cpu_reset_handler) 114 115 115 116 cpsid aif, 0x13 @ SVC mode, interrupts disabled 117 + 118 + mov32 r6, TEGRA_APB_MISC_BASE 119 + ldr r6, [r6, #APB_MISC_GP_HIDREV] 120 + and r6, r6, #0xff00 121 + #ifdef CONFIG_ARCH_TEGRA_2x_SOC 122 + t20_check: 123 + cmp r6, #(0x20 << 8) 124 + bne after_t20_check 125 + t20_errata: 126 + # Tegra20 is a Cortex-A9 r1p1 127 + mrc p15, 0, r0, c1, c0, 0 @ read system control register 128 + orr r0, r0, #1 << 14 @ erratum 716044 129 + mcr p15, 0, r0, c1, c0, 0 @ write system control register 130 + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 131 + orr r0, r0, #1 << 4 @ erratum 742230 132 + orr r0, r0, #1 << 11 @ erratum 751472 133 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 134 + b after_errata 135 + after_t20_check: 136 + #endif 137 + #ifdef CONFIG_ARCH_TEGRA_3x_SOC 138 + t30_check: 139 + cmp r6, #(0x30 << 8) 140 + bne after_t30_check 141 + t30_errata: 142 + # Tegra30 is a Cortex-A9 r2p9 143 + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 144 + orr r0, r0, #1 << 6 @ erratum 743622 145 + orr r0, r0, #1 << 11 @ erratum 751472 146 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 147 + b after_errata 148 + after_t30_check: 149 + #endif 150 + after_errata: 116 151 mrc p15, 0, r10, c0, c0, 5 @ MPIDR 117 152 and r10, r10, #0x3 @ R10 = CPU number 118 153 mov r11, #1 ··· 162 129 163 130 #ifdef CONFIG_ARCH_TEGRA_2x_SOC 164 131 /* Are we on Tegra20? */ 165 - mov32 r6, TEGRA_APB_MISC_BASE 166 - ldr r0, [r6, #APB_MISC_GP_HIDREV] 167 - and r0, r0, #0xff00 168 - cmp r0, #(0x20 << 8) 132 + cmp r6, #(0x20 << 8) 169 133 bne 1f 170 134 /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ 171 - mov32 r6, TEGRA_PMC_BASE 135 + mov32 r5, TEGRA_PMC_BASE 172 136 mov r0, #0 173 137 cmp r10, #0 174 - strne r0, [r6, #PMC_SCRATCH41] 138 + strne r0, [r5, #PMC_SCRATCH41] 175 139 1: 176 140 #endif 177 141
+5 -5
arch/arm/mach-tegra/sleep.h
··· 1 1 /* 2 - * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. 2 + * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved. 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify it 5 5 * under the terms and conditions of the GNU General Public License, ··· 124 124 void tegra_disable_clean_inv_dcache(void); 125 125 126 126 #ifdef CONFIG_HOTPLUG_CPU 127 - void tegra20_hotplug_init(void); 128 - void tegra30_hotplug_init(void); 127 + void tegra20_hotplug_shutdown(void); 128 + void tegra30_hotplug_shutdown(void); 129 + void tegra_hotplug_init(void); 129 130 #else 130 - static inline void tegra20_hotplug_init(void) {} 131 - static inline void tegra30_hotplug_init(void) {} 131 + static inline void tegra_hotplug_init(void) {} 132 132 #endif 133 133 134 134 void tegra20_cpu_shutdown(int cpu);
+104
arch/arm/mach-tegra/tegra114_speedo.c
··· 1 + /* 2 + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #include <linux/kernel.h> 18 + #include <linux/bug.h> 19 + 20 + #include "fuse.h" 21 + 22 + #define CORE_PROCESS_CORNERS_NUM 2 23 + #define CPU_PROCESS_CORNERS_NUM 2 24 + 25 + enum { 26 + THRESHOLD_INDEX_0, 27 + THRESHOLD_INDEX_1, 28 + THRESHOLD_INDEX_COUNT, 29 + }; 30 + 31 + static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = { 32 + {1123, UINT_MAX}, 33 + {0, UINT_MAX}, 34 + }; 35 + 36 + static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = { 37 + {1695, UINT_MAX}, 38 + {0, UINT_MAX}, 39 + }; 40 + 41 + static void rev_sku_to_speedo_ids(int rev, int sku, int *threshold) 42 + { 43 + u32 tmp; 44 + 45 + switch (sku) { 46 + case 0x00: 47 + case 0x10: 48 + case 0x05: 49 + case 0x06: 50 + tegra_cpu_speedo_id = 1; 51 + tegra_soc_speedo_id = 0; 52 + *threshold = THRESHOLD_INDEX_0; 53 + break; 54 + 55 + case 0x03: 56 + case 0x04: 57 + tegra_cpu_speedo_id = 2; 58 + tegra_soc_speedo_id = 1; 59 + *threshold = THRESHOLD_INDEX_1; 60 + break; 61 + 62 + default: 63 + pr_err("Tegra114 Unknown SKU %d\n", sku); 64 + tegra_cpu_speedo_id = 0; 65 + tegra_soc_speedo_id = 0; 66 + *threshold = THRESHOLD_INDEX_0; 67 + break; 68 + } 69 + 70 + if (rev == TEGRA_REVISION_A01) { 71 + tmp = tegra_fuse_readl(0x270) << 1; 72 + tmp |= tegra_fuse_readl(0x26c); 73 + if (!tmp) 74 + tegra_cpu_speedo_id = 0; 75 + } 76 + } 77 + 78 + void tegra114_init_speedo_data(void) 79 + { 80 + u32 cpu_speedo_val; 81 + u32 core_speedo_val; 82 + int threshold; 83 + int i; 84 + 85 + BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != 86 + THRESHOLD_INDEX_COUNT); 87 + BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != 88 + THRESHOLD_INDEX_COUNT); 89 + 90 + rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id, &threshold); 91 + 92 + cpu_speedo_val = tegra_fuse_readl(0x12c) + 1024; 93 + core_speedo_val = tegra_fuse_readl(0x134); 94 + 95 + for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) 96 + if (cpu_speedo_val < cpu_process_speedos[threshold][i]) 97 + break; 98 + tegra_cpu_process_id = i; 99 + 100 + for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) 101 + if (core_speedo_val < core_process_speedos[threshold][i]) 102 + break; 103 + tegra_core_process_id = i; 104 + }
+2 -34
drivers/clk/tegra/clk-tegra20.c
··· 711 711 } 712 712 713 713 static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", 714 - "pll_p_cclk", "pll_p_out4_cclk", 715 - "pll_p_out3_cclk", "clk_d", "pll_x" }; 714 + "pll_p", "pll_p_out4", 715 + "pll_p_out3", "clk_d", "pll_x" }; 716 716 static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", 717 717 "pll_p_out3", "pll_p_out2", "clk_d", 718 718 "clk_32k", "pll_m_out1" }; ··· 720 720 static void tegra20_super_clk_init(void) 721 721 { 722 722 struct clk *clk; 723 - 724 - /* 725 - * DIV_U71 dividers for CCLK, these dividers are used only 726 - * if parent clock is fixed rate. 727 - */ 728 - 729 - /* 730 - * Clock input to cclk divided from pll_p using 731 - * U71 divider of cclk. 732 - */ 733 - clk = tegra_clk_register_divider("pll_p_cclk", "pll_p", 734 - clk_base + SUPER_CCLK_DIVIDER, 0, 735 - TEGRA_DIVIDER_INT, 16, 8, 1, NULL); 736 - clk_register_clkdev(clk, "pll_p_cclk", NULL); 737 - 738 - /* 739 - * Clock input to cclk divided from pll_p_out3 using 740 - * U71 divider of cclk. 741 - */ 742 - clk = tegra_clk_register_divider("pll_p_out3_cclk", "pll_p_out3", 743 - clk_base + SUPER_CCLK_DIVIDER, 0, 744 - TEGRA_DIVIDER_INT, 16, 8, 1, NULL); 745 - clk_register_clkdev(clk, "pll_p_out3_cclk", NULL); 746 - 747 - /* 748 - * Clock input to cclk divided from pll_p_out4 using 749 - * U71 divider of cclk. 750 - */ 751 - clk = tegra_clk_register_divider("pll_p_out4_cclk", "pll_p_out4", 752 - clk_base + SUPER_CCLK_DIVIDER, 0, 753 - TEGRA_DIVIDER_INT, 16, 8, 1, NULL); 754 - clk_register_clkdev(clk, "pll_p_out4_cclk", NULL); 755 723 756 724 /* CCLK */ 757 725 clk = tegra_clk_register_super_mux("cclk", cclk_parents,
+2 -2
drivers/clocksource/tegra20_timer.c
··· 172 172 BUG(); 173 173 } 174 174 175 - clk = clk_get_sys("timer", NULL); 175 + clk = of_clk_get(np, 0); 176 176 if (IS_ERR(clk)) { 177 177 pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n"); 178 178 rate = 12000000; ··· 235 235 * rtc registers are used by read_persistent_clock, keep the rtc clock 236 236 * enabled 237 237 */ 238 - clk = clk_get_sys("rtc-tegra", NULL); 238 + clk = of_clk_get(np, 0); 239 239 if (IS_ERR(clk)) 240 240 pr_warn("Unable to get rtc-tegra clock\n"); 241 241 else
+19 -2
drivers/gpio/gpio-tegra.c
··· 72 72 u32 oe[4]; 73 73 u32 int_enb[4]; 74 74 u32 int_lvl[4]; 75 + u32 wake_enb[4]; 75 76 #endif 76 77 }; 77 78 ··· 334 333 bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio)); 335 334 bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio)); 336 335 bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio)); 336 + 337 + /* Enable gpio irq for wake up source */ 338 + tegra_gpio_writel(bank->wake_enb[p], 339 + GPIO_INT_ENB(gpio)); 337 340 } 338 341 } 339 342 local_irq_restore(flags); 340 343 return 0; 341 344 } 342 345 343 - static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable) 346 + static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) 344 347 { 345 348 struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); 349 + int gpio = d->hwirq; 350 + u32 port, bit, mask; 351 + 352 + port = GPIO_PORT(gpio); 353 + bit = GPIO_BIT(gpio); 354 + mask = BIT(bit); 355 + 356 + if (enable) 357 + bank->wake_enb[port] |= mask; 358 + else 359 + bank->wake_enb[port] &= ~mask; 360 + 346 361 return irq_set_irq_wake(bank->irq, enable); 347 362 } 348 363 #endif ··· 370 353 .irq_unmask = tegra_gpio_irq_unmask, 371 354 .irq_set_type = tegra_gpio_irq_set_type, 372 355 #ifdef CONFIG_PM_SLEEP 373 - .irq_set_wake = tegra_gpio_wake_enable, 356 + .irq_set_wake = tegra_gpio_irq_set_wake, 374 357 #endif 375 358 }; 376 359