Merge tag 'tegra-for-3.9-soc-ccf' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorOlof Johansson <olof@lixom.net>
Tue, 5 Feb 2013 20:13:10 +0000 (12:13 -0800)
committerOlof Johansson <olof@lixom.net>
Tue, 5 Feb 2013 20:13:10 +0000 (12:13 -0800)
From Stephen Warren:
ARM: tegra: Common Clock Framework rework

Tegra already supports the common clock framework, but had issues:

1) The clock driver was located in arch/arm/mach-tegra/ rather than
   drivers/clk/.

2) A single "Tegra clock" type was implemented, rather than separate
   clock types for PLL, mux, divider, ... type in HW.

3) Clock lookups by device drivers were still driven by device name
   and connection ID, rather than through device tree.

This pull request solves all three issues. This required some DT changes
to add clocks properties, and driver changes to request clocks more
"correctly". Finally, this rework allows all AUXDATA to be removed from
Tegra board files, and various duplicate clock lookup entries to be
removed from the driver.

This pull request is based on the previous pull request, with tag
tegra-for-3.9-cleanup.

* tag 'tegra-for-3.9-soc-ccf' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra: (31 commits)
  clk: tegra30: remove unused TEGRA_CLK_DUPLICATE()s
  clk: tegra20: remove unused TEGRA_CLK_DUPLICATE()s
  ARM: tegra30: remove auxdata
  ARM: tegra20: remove auxdata
  ASoC: tegra: remove auxdata
  staging: nvec: remove use of clk_get_sys
  ARM: tegra: paz00: add clock information to DT
  ARM: tegra: add clock properties to Tegra30 DT
  ARM: tegra: add clock properties to Tegra20 DT
  spi: tegra: do not use clock name to get clock
  ARM: tegra: remove legacy clock code
  ARM: tegra: migrate to new clock code
  clk: tegra: add clock support for Tegra30
  clk: tegra: add clock support for Tegra20
  clk: tegra: add Tegra specific clocks
  ARM: tegra: define Tegra30 CAR binding
  ARM: tegra: define Tegra20 CAR binding
  ARM: tegra: move tegra_cpu_car.h to linux/clk/tegra.h
  ARM: tegra: add function to read chipid
  ARM: tegra: fix compile error when disable CPU_IDLE
  ...

Signed-off-by: Olof Johansson <olof@lixom.net>
Conflicts:
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/board-dt-tegra30.c
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/platsmp.c
drivers/clocksource/Makefile

1  2 
arch/arm/Kconfig
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/board-dt-tegra30.c
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/platsmp.c
drivers/clocksource/Makefile
drivers/clocksource/tegra20_timer.c
drivers/dma/tegra20-apb-dma.c

diff --combined arch/arm/Kconfig
index a3ffd1a391a70b36cd12acbb9b96b0d86ffd17d6,eb9fc2f8acf10b2cd56a98430caf7246a9abc3a3..22bfac3e69757481f7212080027d5aecc4a13063
@@@ -393,7 -393,6 +393,7 @@@ config ARCH_GEMIN
  config ARCH_SIRF
        bool "CSR SiRF"
        select ARCH_REQUIRE_GPIOLIB
 +      select AUTO_ZRELADDR
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
@@@ -643,6 -642,7 +643,7 @@@ config ARCH_TEGR
        select ARCH_HAS_CPUFREQ
        select CLKDEV_LOOKUP
        select CLKSRC_MMIO
+       select CLKSRC_OF
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
        select GENERIC_GPIO
@@@ -950,6 -950,22 +951,6 @@@ config ARCH_OMA
        help
          Support for TI's OMAP platform (OMAP1/2/3/4).
  
 -config ARCH_VT8500_SINGLE
 -      bool "VIA/WonderMedia 85xx"
 -      select ARCH_HAS_CPUFREQ
 -      select ARCH_REQUIRE_GPIOLIB
 -      select CLKDEV_LOOKUP
 -      select COMMON_CLK
 -      select CPU_ARM926T
 -      select GENERIC_CLOCKEVENTS
 -      select GENERIC_GPIO
 -      select HAVE_CLK
 -      select MULTI_IRQ_HANDLER
 -      select SPARSE_IRQ
 -      select USE_OF
 -      help
 -        Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
 -
  endchoice
  
  menu "Multiple platform selection"
index 5ed81bab2d4bb4eb6aaf561200c400cc8d1cc506,5049edf68f4f2e2e42792ed637f83bab0b263f61..abdbe9e658f96afb0c28834b50f46e331281514a
@@@ -15,6 -15,7 +15,7 @@@
   *
   */
  
+ #include <linux/clocksource.h>
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/platform_device.h>
@@@ -25,6 -26,7 +26,6 @@@
  #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 <linux/pda_power.h>
  #include <linux/platform_data/tegra_usb.h>
  #include <linux/i2c-tegra.h>
  #include <linux/usb/tegra_usb_phy.h>
  
 -#include <asm/hardware/gic.h>
  #include <asm/mach-types.h>
  #include <asm/mach/arch.h>
  #include <asm/mach/time.h>
  #include <asm/setup.h>
  
  #include "board.h"
- #include "clock.h"
  #include "common.h"
  #include "iomap.h"
  
- struct tegra_ehci_platform_data tegra_ehci1_pdata = {
+ static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
        .operating_mode = TEGRA_USB_OTG,
        .power_down_on_bus_suspend = 1,
        .vbus_gpio = -1,
  };
  
- struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
+ static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
        .reset_gpio = -1,
        .clk = "cdev2",
  };
  
- struct tegra_ehci_platform_data tegra_ehci2_pdata = {
+ static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
        .phy_config = &tegra_ehci2_ulpi_phy_config,
        .operating_mode = TEGRA_USB_HOST,
        .power_down_on_bus_suspend = 1,
        .vbus_gpio = -1,
  };
  
- struct tegra_ehci_platform_data tegra_ehci3_pdata = {
+ static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
        .operating_mode = TEGRA_USB_HOST,
        .power_down_on_bus_suspend = 1,
        .vbus_gpio = -1,
  };
  
- struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC4_BASE, "sdhci-tegra.3", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c-dvc", TEGRA_DVC_BASE, "tegra-i2c.3", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra20-i2s.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S2_BASE, "tegra20-i2s.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra20-das", NULL),
+ static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
        OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB_BASE, "tegra-ehci.0",
                       &tegra_ehci1_pdata),
        OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1",
                       &tegra_ehci2_pdata),
        OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2",
                       &tegra_ehci3_pdata),
-       OF_DEV_AUXDATA("nvidia,tegra20-apbdma", TEGRA_APB_DMA_BASE, "tegra-apbdma", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-sflash", 0x7000c380, "spi", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D400, "spi_tegra.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D600, "spi_tegra.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D800, "spi_tegra.2", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000DA00, "spi_tegra.3", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-host1x", 0x50000000, "host1x", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54200000, "tegradc.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54240000, "tegradc.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-hdmi", 0x54280000, "hdmi", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-dsi", 0x54300000, "dsi", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-tvo", 0x542c0000, "tvo", NULL),
        {}
  };
  
- static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
-       /* name         parent          rate            enabled */
-       { "uarta",      "pll_p",        216000000,      true },
-       { "uartd",      "pll_p",        216000000,      true },
-       { "usbd",       "clk_m",        12000000,       false },
-       { "usb2",       "clk_m",        12000000,       false },
-       { "usb3",       "clk_m",        12000000,       false },
-       { "pll_a",      "pll_p_out1",   56448000,       true },
-       { "pll_a_out0", "pll_a",        11289600,       true },
-       { "cdev1",      NULL,           0,              true },
-       { "blink",      "clk_32k",      32768,          true },
-       { "i2s1",       "pll_a_out0",   11289600,       false},
-       { "i2s2",       "pll_a_out0",   11289600,       false},
-       { "sdmmc1",     "pll_p",        48000000,       false},
-       { "sdmmc3",     "pll_p",        48000000,       false},
-       { "sdmmc4",     "pll_p",        48000000,       false},
-       { "spi",        "pll_p",        20000000,       false },
-       { "sbc1",       "pll_p",        100000000,      false },
-       { "sbc2",       "pll_p",        100000000,      false },
-       { "sbc3",       "pll_p",        100000000,      false },
-       { "sbc4",       "pll_p",        100000000,      false },
-       { "host1x",     "pll_c",        150000000,      false },
-       { "disp1",      "pll_p",        600000000,      false },
-       { "disp2",      "pll_p",        600000000,      false },
-       { NULL,         NULL,           0,              0},
- };
  static void __init tegra_dt_init(void)
  {
-       tegra_clk_init_from_table(tegra_dt_clk_init_table);
        /*
         * Finished with the static registrations now; fill in the missing
         * devices
@@@ -200,7 -149,8 +147,7 @@@ DT_MACHINE_START(TEGRA_DT, "nVidia Tegr
        .smp            = smp_ops(tegra_smp_ops),
        .init_early     = tegra20_init_early,
        .init_irq       = tegra_dt_init_irq,
-       .init_time      = tegra_init_timer,
 -      .handle_irq     = gic_handle_irq,
+       .init_time      = clocksource_of_init,
        .init_machine   = tegra_dt_init,
        .init_late      = tegra_dt_init_late,
        .restart        = tegra_assert_system_reset,
index 12dc2ddeca640914c694d92a0735813de37c6591,5b58b6439db6c9b08322a2dc609a259b330bd003..bf68567e549d6e011d266eca8e11efe88942cf1e
@@@ -23,6 -23,7 +23,7 @@@
   *
   */
  
+ #include <linux/clocksource.h>
  #include <linux/kernel.h>
  #include <linux/of.h>
  #include <linux/of_address.h>
  #include <linux/of_platform.h>
  
  #include <asm/mach/arch.h>
 -#include <asm/hardware/gic.h>
  
  #include "board.h"
- #include "clock.h"
  #include "common.h"
  #include "iomap.h"
  
- struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000600, "sdhci-tegra.3", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C000, "tegra-i2c.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C400, "tegra-i2c.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D400, "spi_tegra.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D600, "spi_tegra.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D800, "spi_tegra.2", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DA00, "spi_tegra.3", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DC00, "spi_tegra.4", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DE00, "spi_tegra.5", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-host1x", 0x50000000, "host1x", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54200000, "tegradc.0", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54240000, "tegradc.1", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-hdmi", 0x54280000, "hdmi", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-dsi", 0x54300000, "dsi", NULL),
-       OF_DEV_AUXDATA("nvidia,tegra30-tvo", 0x542c0000, "tvo", NULL),
-       {}
- };
- static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
-       /* name         parent          rate            enabled */
-       { "uarta",      "pll_p",        408000000,      true },
-       { "pll_a",      "pll_p_out1",   564480000,      true },
-       { "pll_a_out0", "pll_a",        11289600,       true },
-       { "extern1",    "pll_a_out0",   0,              true },
-       { "clk_out_1",  "extern1",      0,              true },
-       { "blink",      "clk_32k",      32768,          true },
-       { "i2s0",       "pll_a_out0",   11289600,       false},
-       { "i2s1",       "pll_a_out0",   11289600,       false},
-       { "i2s2",       "pll_a_out0",   11289600,       false},
-       { "i2s3",       "pll_a_out0",   11289600,       false},
-       { "i2s4",       "pll_a_out0",   11289600,       false},
-       { "sdmmc1",     "pll_p",        48000000,       false},
-       { "sdmmc3",     "pll_p",        48000000,       false},
-       { "sdmmc4",     "pll_p",        48000000,       false},
-       { "sbc1",       "pll_p",        100000000,      false},
-       { "sbc2",       "pll_p",        100000000,      false},
-       { "sbc3",       "pll_p",        100000000,      false},
-       { "sbc4",       "pll_p",        100000000,      false},
-       { "sbc5",       "pll_p",        100000000,      false},
-       { "sbc6",       "pll_p",        100000000,      false},
-       { "host1x",     "pll_c",        150000000,      false},
-       { "disp1",      "pll_p",        600000000,      false},
-       { "disp2",      "pll_p",        600000000,      false},
-       { NULL,         NULL,           0,              0},
- };
  static void __init tegra30_dt_init(void)
  {
-       tegra_clk_init_from_table(tegra_dt_clk_init_table);
-       of_platform_populate(NULL, of_default_bus_match_table,
-                               tegra30_auxdata_lookup, NULL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  }
  
  static const char *tegra30_dt_board_compat[] = {
@@@ -111,7 -53,8 +52,7 @@@ DT_MACHINE_START(TEGRA30_DT, "NVIDIA Te
        .map_io         = tegra_map_common_io,
        .init_early     = tegra30_init_early,
        .init_irq       = tegra_dt_init_irq,
-       .init_time      = tegra_init_timer,
 -      .handle_irq     = gic_handle_irq,
+       .init_time      = clocksource_of_init,
        .init_machine   = tegra30_dt_init,
        .init_late      = tegra_init_late,
        .restart        = tegra_assert_system_reset,
index 3599959517b3059b63277163d5f6ab8e7c67b854,87dd69ccdf8e55ffe4747818d485424e9cc75b03..46c071861c4eab9c2f173adc6f9ef8efe3914935
  #include <linux/io.h>
  #include <linux/clk.h>
  #include <linux/delay.h>
 -#include <linux/of_irq.h>
 +#include <linux/irqchip.h>
+ #include <linux/clk/tegra.h>
  
  #include <asm/hardware/cache-l2x0.h>
 -#include <asm/hardware/gic.h>
  
  #include <mach/powergate.h>
  
  #include "board.h"
- #include "clock.h"
  #include "common.h"
  #include "fuse.h"
  #include "iomap.h"
@@@ -36,6 -37,7 +36,7 @@@
  #include "apbio.h"
  #include "sleep.h"
  #include "pm.h"
+ #include "reset.h"
  
  /*
   * Storage for debug-macro.S's state.
@@@ -56,10 -58,16 +57,11 @@@ u32 tegra_uart_config[4] = 
  };
  
  #ifdef CONFIG_OF
 -static const struct of_device_id tegra_dt_irq_match[] __initconst = {
 -      { .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
 -      { }
 -};
 -
  void __init tegra_dt_init_irq(void)
  {
+       tegra_clocks_init();
        tegra_init_irq();
 -      of_irq_init(tegra_dt_irq_match);
 +      irqchip_init();
  }
  #endif
  
@@@ -73,43 -81,6 +75,6 @@@ void tegra_assert_system_reset(char mod
        writel_relaxed(reg, reset);
  }
  
- #ifdef CONFIG_ARCH_TEGRA_2x_SOC
- static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = {
-       /* name         parent          rate            enabled */
-       { "clk_m",      NULL,           0,              true },
-       { "pll_p",      "clk_m",        216000000,      true },
-       { "pll_p_out1", "pll_p",        28800000,       true },
-       { "pll_p_out2", "pll_p",        48000000,       true },
-       { "pll_p_out3", "pll_p",        72000000,       true },
-       { "pll_p_out4", "pll_p",        24000000,       true },
-       { "pll_c",      "clk_m",        600000000,      true },
-       { "pll_c_out1", "pll_c",        120000000,      true },
-       { "sclk",       "pll_c_out1",   120000000,      true },
-       { "hclk",       "sclk",         120000000,      true },
-       { "pclk",       "hclk",         60000000,       true },
-       { "csite",      NULL,           0,              true },
-       { "emc",        NULL,           0,              true },
-       { "cpu",        NULL,           0,              true },
-       { NULL,         NULL,           0,              0},
- };
- #endif
- #ifdef CONFIG_ARCH_TEGRA_3x_SOC
- static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = {
-       /* name         parent          rate            enabled */
-       { "clk_m",      NULL,           0,              true },
-       { "pll_p",      "pll_ref",      408000000,      true },
-       { "pll_p_out1", "pll_p",        9600000,        true },
-       { "pll_p_out4", "pll_p",        102000000,      true },
-       { "sclk",       "pll_p_out4",   102000000,      true },
-       { "hclk",       "sclk",         102000000,      true },
-       { "pclk",       "hclk",         51000000,       true },
-       { "csite",      NULL,           0,              true },
-       { NULL,         NULL,           0,              0},
- };
- #endif
  static void __init tegra_init_cache(void)
  {
  #ifdef CONFIG_CACHE_L2X0
  #ifdef CONFIG_ARCH_TEGRA_2x_SOC
  void __init tegra20_init_early(void)
  {
+       tegra_cpu_reset_handler_init();
        tegra_apb_io_init();
        tegra_init_fuse();
-       tegra2_init_clocks();
-       tegra_clk_init_from_table(tegra20_clk_init_table);
        tegra_init_cache();
        tegra_pmc_init();
        tegra_powergate_init();
  #ifdef CONFIG_ARCH_TEGRA_3x_SOC
  void __init tegra30_init_early(void)
  {
+       tegra_cpu_reset_handler_init();
        tegra_apb_io_init();
        tegra_init_fuse();
-       tegra30_init_clocks();
-       tegra_clk_init_from_table(tegra30_clk_init_table);
        tegra_init_cache();
        tegra_pmc_init();
        tegra_powergate_init();
index 18d7290cf93b63dbe592591bfb6b4ed87be76ff0,3ec7fc487857af2d3fa56152982ccbe4c6f8d459..c72e249e33b0740ca90f63d3834ae7c971375f4e
  #include <linux/jiffies.h>
  #include <linux/smp.h>
  #include <linux/io.h>
 +#include <linux/irqchip/arm-gic.h>
+ #include <linux/clk/tegra.h>
  
  #include <asm/cacheflush.h>
 -#include <asm/hardware/gic.h>
  #include <asm/mach-types.h>
  #include <asm/smp_scu.h>
+ #include <asm/smp_plat.h>
  
  #include <mach/powergate.h>
  
  #include "fuse.h"
  #include "flowctrl.h"
  #include "reset.h"
- #include "tegra_cpu_car.h"
  
  #include "common.h"
  #include "iomap.h"
  
  extern void tegra_secondary_startup(void);
  
+ static cpumask_t tegra_cpu_init_mask;
  static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
  
  #define EVP_CPU_RESET_VECTOR \
@@@ -50,6 -52,7 +52,7 @@@ static void __cpuinit tegra_secondary_i
         */
        gic_secondary_init(0);
  
+       cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
  }
  
  static int tegra20_power_up_cpu(unsigned int cpu)
@@@ -72,14 -75,42 +75,42 @@@ static int tegra30_power_up_cpu(unsigne
        if (pwrgateid < 0)
                return pwrgateid;
  
-       /* If this is the first boot, toggle powergates directly. */
+       /*
+        * The power up sequence of cold boot CPU and warm boot CPU
+        * was different.
+        *
+        * For warm boot CPU that was resumed from CPU hotplug, the
+        * power will be resumed automatically after un-halting the
+        * flow controller of the warm boot CPU. We need to wait for
+        * the confirmaiton that the CPU is powered then removing
+        * 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()
+        * 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))
+                               goto remove_clamps;
+                       udelay(10);
+               } while (time_before(jiffies, timeout));
+       }
+       /*
+        * The power status of the cold boot CPU is power gated as
+        * default. To power up the cold boot CPU, the power should
+        * be un-gated by un-toggling the power gate register
+        * manually.
+        */
        if (!tegra_powergate_is_powered(pwrgateid)) {
                ret = tegra_powergate_power_on(pwrgateid);
                if (ret)
                        return ret;
  
                /* Wait for the power to come up. */
-               timeout = jiffies + 10*HZ;
+               timeout = jiffies + msecs_to_jiffies(100);
                while (tegra_powergate_is_powered(pwrgateid)) {
                        if (time_after(jiffies, timeout))
                                return -ETIMEDOUT;
                }
        }
  
+ remove_clamps:
        /* CPU partition is powered. Enable the CPU clock. */
        tegra_enable_cpu_clock(cpu);
        udelay(10);
@@@ -105,6 -137,8 +137,8 @@@ static int __cpuinit tegra_boot_seconda
  {
        int status;
  
+       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
@@@ -159,11 -193,15 +193,13 @@@ static void __init tegra_smp_init_cpus(
  
        for (i = 0; i < ncores; i++)
                set_cpu_possible(i, true);
 -
 -      set_smp_cross_call(gic_raise_softirq);
  }
  
  static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
  {
-       tegra_cpu_reset_handler_init();
+       /* Always mark the boot CPU (CPU0) as initialized. */
+       cpumask_set_cpu(0, &tegra_cpu_init_mask);
        scu_enable(scu_base);
  }
  
@@@ -173,6 -211,7 +209,7 @@@ struct smp_operations tegra_smp_ops __i
        .smp_secondary_init     = tegra_secondary_init,
        .smp_boot_secondary     = tegra_boot_secondary,
  #ifdef CONFIG_HOTPLUG_CPU
+       .cpu_kill               = tegra_cpu_kill,
        .cpu_die                = tegra_cpu_die,
        .cpu_disable            = tegra_cpu_disable,
  #endif
index 440449c1ca21e139e7c5d79e19c0feab9934e550,b5cc50796a809e80f8623a77f0b22126d7bd8fea..596c45c2f192114224f6626f786401f5b41656a6
@@@ -17,6 -17,6 +17,7 @@@ obj-$(CONFIG_CLKSRC_DBX500_PRCMU)     += cl
  obj-$(CONFIG_ARMADA_370_XP_TIMER)     += time-armada-370-xp.o
  obj-$(CONFIG_ARCH_BCM2835)    += bcm2835_timer.o
  obj-$(CONFIG_SUNXI_TIMER)     += sunxi_timer.o
+ obj-$(CONFIG_ARCH_TEGRA)      += tegra20_timer.o
 +obj-$(CONFIG_VT8500_TIMER)    += vt8500_timer.o
  
  obj-$(CONFIG_CLKSRC_ARM_GENERIC)      += arm_generic.o
index 0000000000000000000000000000000000000000,5bc14299de3cb3a698af94f26c0ed7e16a9e5b76..0bde03feb095365602af6fe0239a5d13b26181b3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,285 +1,281 @@@
 -      clockevents_calc_mult_shift(&tegra_clockevent, 1000000, 5);
 -      tegra_clockevent.max_delta_ns =
 -              clockevent_delta2ns(0x1fffffff, &tegra_clockevent);
 -      tegra_clockevent.min_delta_ns =
 -              clockevent_delta2ns(0x1, &tegra_clockevent);
+ /*
+  * Copyright (C) 2010 Google, Inc.
+  *
+  * Author:
+  *    Colin Cross <ccross@google.com>
+  *
+  * 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/init.h>
+ #include <linux/err.h>
+ #include <linux/time.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/clockchips.h>
+ #include <linux/clocksource.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <asm/mach/time.h>
+ #include <asm/smp_twd.h>
+ #include <asm/sched_clock.h>
+ #define RTC_SECONDS            0x08
+ #define RTC_SHADOW_SECONDS     0x0c
+ #define RTC_MILLISECONDS       0x10
+ #define TIMERUS_CNTR_1US 0x10
+ #define TIMERUS_USEC_CFG 0x14
+ #define TIMERUS_CNTR_FREEZE 0x4c
+ #define TIMER1_BASE 0x0
+ #define TIMER2_BASE 0x8
+ #define TIMER3_BASE 0x50
+ #define TIMER4_BASE 0x58
+ #define TIMER_PTV 0x0
+ #define TIMER_PCR 0x4
+ static void __iomem *timer_reg_base;
+ static void __iomem *rtc_base;
+ static struct timespec persistent_ts;
+ static u64 persistent_ms, last_persistent_ms;
+ #define timer_writel(value, reg) \
+       __raw_writel(value, timer_reg_base + (reg))
+ #define timer_readl(reg) \
+       __raw_readl(timer_reg_base + (reg))
+ static int tegra_timer_set_next_event(unsigned long cycles,
+                                        struct clock_event_device *evt)
+ {
+       u32 reg;
+       reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0);
+       timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+       return 0;
+ }
+ static void tegra_timer_set_mode(enum clock_event_mode mode,
+                                   struct clock_event_device *evt)
+ {
+       u32 reg;
+       timer_writel(0, TIMER3_BASE + TIMER_PTV);
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               reg = 0xC0000000 | ((1000000/HZ)-1);
+               timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               break;
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+ }
+ static struct clock_event_device tegra_clockevent = {
+       .name           = "timer0",
+       .rating         = 300,
+       .features       = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+       .set_next_event = tegra_timer_set_next_event,
+       .set_mode       = tegra_timer_set_mode,
+ };
+ static u32 notrace tegra_read_sched_clock(void)
+ {
+       return timer_readl(TIMERUS_CNTR_1US);
+ }
+ /*
+  * tegra_rtc_read - Reads the Tegra RTC registers
+  * Care must be taken that this funciton is not called while the
+  * tegra_rtc driver could be executing to avoid race conditions
+  * on the RTC shadow register
+  */
+ static u64 tegra_rtc_read_ms(void)
+ {
+       u32 ms = readl(rtc_base + RTC_MILLISECONDS);
+       u32 s = readl(rtc_base + RTC_SHADOW_SECONDS);
+       return (u64)s * MSEC_PER_SEC + ms;
+ }
+ /*
+  * tegra_read_persistent_clock -  Return time from a persistent clock.
+  *
+  * Reads the time from a source which isn't disabled during PM, the
+  * 32k sync timer.  Convert the cycles elapsed since last read into
+  * nsecs and adds to a monotonically increasing timespec.
+  * Care must be taken that this funciton is not called while the
+  * tegra_rtc driver could be executing to avoid race conditions
+  * on the RTC shadow register
+  */
+ static void tegra_read_persistent_clock(struct timespec *ts)
+ {
+       u64 delta;
+       struct timespec *tsp = &persistent_ts;
+       last_persistent_ms = persistent_ms;
+       persistent_ms = tegra_rtc_read_ms();
+       delta = persistent_ms - last_persistent_ms;
+       timespec_add_ns(tsp, delta * NSEC_PER_MSEC);
+       *ts = *tsp;
+ }
+ static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
+ {
+       struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+       timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
+       evt->event_handler(evt);
+       return IRQ_HANDLED;
+ }
+ static struct irqaction tegra_timer_irq = {
+       .name           = "timer0",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
+       .handler        = tegra_timer_interrupt,
+       .dev_id         = &tegra_clockevent,
+ };
+ static const struct of_device_id timer_match[] __initconst = {
+       { .compatible = "nvidia,tegra20-timer" },
+       {}
+ };
+ static const struct of_device_id rtc_match[] __initconst = {
+       { .compatible = "nvidia,tegra20-rtc" },
+       {}
+ };
+ static void __init tegra20_init_timer(void)
+ {
+       struct device_node *np;
+       struct clk *clk;
+       unsigned long rate;
+       int ret;
+       np = of_find_matching_node(NULL, timer_match);
+       if (!np) {
+               pr_err("Failed to find timer DT node\n");
+               BUG();
+       }
+       timer_reg_base = of_iomap(np, 0);
+       if (!timer_reg_base) {
+               pr_err("Can't map timer registers\n");
+               BUG();
+       }
+       tegra_timer_irq.irq = irq_of_parse_and_map(np, 2);
+       if (tegra_timer_irq.irq <= 0) {
+               pr_err("Failed to map timer IRQ\n");
+               BUG();
+       }
+       clk = clk_get_sys("timer", NULL);
+       if (IS_ERR(clk)) {
+               pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
+               rate = 12000000;
+       } else {
+               clk_prepare_enable(clk);
+               rate = clk_get_rate(clk);
+       }
+       of_node_put(np);
+       np = of_find_matching_node(NULL, rtc_match);
+       if (!np) {
+               pr_err("Failed to find RTC DT node\n");
+               BUG();
+       }
+       rtc_base = of_iomap(np, 0);
+       if (!rtc_base) {
+               pr_err("Can't map RTC registers");
+               BUG();
+       }
+       /*
+        * rtc registers are used by read_persistent_clock, keep the rtc clock
+        * enabled
+        */
+       clk = clk_get_sys("rtc-tegra", NULL);
+       if (IS_ERR(clk))
+               pr_warn("Unable to get rtc-tegra clock\n");
+       else
+               clk_prepare_enable(clk);
+       of_node_put(np);
+       switch (rate) {
+       case 12000000:
+               timer_writel(0x000b, TIMERUS_USEC_CFG);
+               break;
+       case 13000000:
+               timer_writel(0x000c, TIMERUS_USEC_CFG);
+               break;
+       case 19200000:
+               timer_writel(0x045f, TIMERUS_USEC_CFG);
+               break;
+       case 26000000:
+               timer_writel(0x0019, TIMERUS_USEC_CFG);
+               break;
+       default:
+               WARN(1, "Unknown clock rate");
+       }
+       setup_sched_clock(tegra_read_sched_clock, 32, 1000000);
+       if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
+               "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) {
+               pr_err("Failed to register clocksource\n");
+               BUG();
+       }
+       ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
+       if (ret) {
+               pr_err("Failed to register timer IRQ: %d\n", ret);
+               BUG();
+       }
 -      clockevents_register_device(&tegra_clockevent);
+       tegra_clockevent.cpumask = cpu_all_mask;
+       tegra_clockevent.irq = tegra_timer_irq.irq;
++      clockevents_config_and_register(&tegra_clockevent, 1000000,
++                                      0x1, 0x1fffffff);
+ #ifdef CONFIG_HAVE_ARM_TWD
+       twd_local_timer_of_register();
+ #endif
+       register_persistent_clock(NULL, tegra_read_persistent_clock);
+ }
+ CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer);
+ #ifdef CONFIG_PM
+ static u32 usec_config;
+ void tegra_timer_suspend(void)
+ {
+       usec_config = timer_readl(TIMERUS_USEC_CFG);
+ }
+ void tegra_timer_resume(void)
+ {
+       timer_writel(usec_config, TIMERUS_USEC_CFG);
+ }
+ #endif
index 3cad856fe67f9f9518cbf79b0f02bd41c32733b8,afc9b89e20f4c9d22c0eb251a1f6b426bef844ca..2a02c11890ecc0c8274271e32dda8fda4075bd00
@@@ -31,8 -31,8 +31,8 @@@
  #include <linux/platform_device.h>
  #include <linux/pm_runtime.h>
  #include <linux/slab.h>
+ #include <linux/clk/tegra.h>
  
- #include <mach/clk.h>
  #include "dmaengine.h"
  
  #define TEGRA_APBDMA_GENERAL                  0x0
@@@ -266,7 -266,6 +266,7 @@@ static struct tegra_dma_desc *tegra_dma
                if (async_tx_test_ack(&dma_desc->txd)) {
                        list_del(&dma_desc->node);
                        spin_unlock_irqrestore(&tdc->lock, flags);
 +                      dma_desc->txd.flags = 0;
                        return dma_desc;
                }
        }
@@@ -1051,9 -1050,7 +1051,9 @@@ struct dma_async_tx_descriptor *tegra_d
                                        TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT;
        ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
  
 -      csr |= TEGRA_APBDMA_CSR_FLOW | TEGRA_APBDMA_CSR_IE_EOC;
 +      csr |= TEGRA_APBDMA_CSR_FLOW;
 +      if (flags & DMA_PREP_INTERRUPT)
 +              csr |= TEGRA_APBDMA_CSR_IE_EOC;
        csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
  
        apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
                mem += len;
        }
        sg_req->last_sg = true;
 -      dma_desc->txd.flags = 0;
 +      if (flags & DMA_CTRL_ACK)
 +              dma_desc->txd.flags = DMA_CTRL_ACK;
  
        /*
         * Make sure that mode should not be conflicting with currently
This page took 0.060107 seconds and 5 git commands to generate.