2011-07-20 06:26:54 +07:00
|
|
|
/*
|
2013-02-14 00:15:50 +07:00
|
|
|
* NVIDIA Tegra SoC device tree board support
|
2011-07-20 06:26:54 +07:00
|
|
|
*
|
2013-02-14 00:15:50 +07:00
|
|
|
* Copyright (C) 2011, 2013, NVIDIA Corporation
|
2011-07-20 06:26:54 +07:00
|
|
|
* Copyright (C) 2010 Secret Lab Technologies, Ltd.
|
|
|
|
* Copyright (C) 2010 Google, Inc.
|
|
|
|
*
|
|
|
|
* This software is licensed under the terms of the GNU General Public
|
|
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
|
|
* may be copied, distributed, and modified under those terms.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-10-24 00:52:53 +07:00
|
|
|
#include <linux/clocksource.h>
|
2011-07-20 06:26:54 +07:00
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/serial_8250.h>
|
|
|
|
#include <linux/clk.h>
|
|
|
|
#include <linux/dma-mapping.h>
|
|
|
|
#include <linux/irqdomain.h>
|
|
|
|
#include <linux/of.h>
|
|
|
|
#include <linux/of_address.h>
|
|
|
|
#include <linux/of_fdt.h>
|
|
|
|
#include <linux/of_platform.h>
|
|
|
|
#include <linux/pda_power.h>
|
2012-08-28 04:22:48 +07:00
|
|
|
#include <linux/platform_data/tegra_usb.h>
|
2011-07-20 06:26:54 +07:00
|
|
|
#include <linux/io.h>
|
2013-03-14 07:48:40 +07:00
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/sys_soc.h>
|
2012-08-28 04:22:48 +07:00
|
|
|
#include <linux/usb/tegra_usb_phy.h>
|
2013-03-26 02:22:24 +07:00
|
|
|
#include <linux/clk/tegra.h>
|
2011-07-20 06:26:54 +07:00
|
|
|
|
|
|
|
#include <asm/mach-types.h>
|
|
|
|
#include <asm/mach/arch.h>
|
|
|
|
#include <asm/mach/time.h>
|
|
|
|
#include <asm/setup.h>
|
|
|
|
|
|
|
|
#include "board.h"
|
2011-09-08 19:15:22 +07:00
|
|
|
#include "common.h"
|
2013-03-14 07:48:40 +07:00
|
|
|
#include "fuse.h"
|
2012-10-05 03:24:09 +07:00
|
|
|
#include "iomap.h"
|
2012-08-28 04:22:48 +07:00
|
|
|
|
2013-01-03 13:27:05 +07:00
|
|
|
static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
|
2012-08-28 04:22:48 +07:00
|
|
|
.operating_mode = TEGRA_USB_OTG,
|
|
|
|
.power_down_on_bus_suspend = 1,
|
|
|
|
.vbus_gpio = -1,
|
|
|
|
};
|
|
|
|
|
2013-01-03 13:27:05 +07:00
|
|
|
static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
|
2012-08-28 04:22:48 +07:00
|
|
|
.reset_gpio = -1,
|
|
|
|
.clk = "cdev2",
|
|
|
|
};
|
|
|
|
|
2013-01-03 13:27:05 +07:00
|
|
|
static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
|
2012-08-28 04:22:48 +07:00
|
|
|
.phy_config = &tegra_ehci2_ulpi_phy_config,
|
|
|
|
.operating_mode = TEGRA_USB_HOST,
|
|
|
|
.power_down_on_bus_suspend = 1,
|
|
|
|
.vbus_gpio = -1,
|
|
|
|
};
|
|
|
|
|
2013-01-03 13:27:05 +07:00
|
|
|
static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
|
2012-08-28 04:22:48 +07:00
|
|
|
.operating_mode = TEGRA_USB_HOST,
|
|
|
|
.power_down_on_bus_suspend = 1,
|
|
|
|
.vbus_gpio = -1,
|
|
|
|
};
|
2011-07-20 06:26:54 +07:00
|
|
|
|
2013-01-03 13:27:05 +07:00
|
|
|
static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
|
2012-12-18 01:31:01 +07:00
|
|
|
OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0",
|
2012-03-20 02:57:13 +07:00
|
|
|
&tegra_ehci1_pdata),
|
2012-12-18 01:31:01 +07:00
|
|
|
OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1",
|
2012-03-20 02:57:13 +07:00
|
|
|
&tegra_ehci2_pdata),
|
2012-12-18 01:31:01 +07:00
|
|
|
OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2",
|
2012-03-20 02:57:13 +07:00
|
|
|
&tegra_ehci3_pdata),
|
2011-07-20 06:26:54 +07:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
static void __init tegra_dt_init(void)
|
|
|
|
{
|
2013-03-14 07:48:40 +07:00
|
|
|
struct soc_device_attribute *soc_dev_attr;
|
|
|
|
struct soc_device *soc_dev;
|
|
|
|
struct device *parent = NULL;
|
|
|
|
|
2013-03-26 02:22:24 +07:00
|
|
|
tegra_clocks_apply_init_table();
|
|
|
|
|
2013-03-14 07:48:40 +07:00
|
|
|
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
|
|
|
if (!soc_dev_attr)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra");
|
|
|
|
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_revision);
|
|
|
|
soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", tegra_chip_id);
|
|
|
|
|
|
|
|
soc_dev = soc_device_register(soc_dev_attr);
|
|
|
|
if (IS_ERR(soc_dev)) {
|
|
|
|
kfree(soc_dev_attr->family);
|
|
|
|
kfree(soc_dev_attr->revision);
|
|
|
|
kfree(soc_dev_attr->soc_id);
|
|
|
|
kfree(soc_dev_attr);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
parent = soc_device_to_device(soc_dev);
|
|
|
|
|
2011-12-17 05:12:32 +07:00
|
|
|
/*
|
|
|
|
* Finished with the static registrations now; fill in the missing
|
|
|
|
* devices
|
|
|
|
*/
|
2013-03-14 07:48:40 +07:00
|
|
|
out:
|
2012-06-29 05:29:19 +07:00
|
|
|
of_platform_populate(NULL, of_default_bus_match_table,
|
2013-03-14 07:48:40 +07:00
|
|
|
tegra20_auxdata_lookup, parent);
|
2011-07-20 06:26:54 +07:00
|
|
|
}
|
|
|
|
|
2012-05-03 02:43:26 +07:00
|
|
|
static void __init trimslice_init(void)
|
|
|
|
{
|
2012-08-04 03:55:36 +07:00
|
|
|
#ifdef CONFIG_TEGRA_PCI
|
2012-05-03 02:43:26 +07:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = tegra_pcie_init(true, true);
|
|
|
|
if (ret)
|
|
|
|
pr_err("tegra_pci_init() failed: %d\n", ret);
|
|
|
|
#endif
|
2012-08-04 03:55:36 +07:00
|
|
|
}
|
2012-05-03 02:43:26 +07:00
|
|
|
|
2012-05-03 04:47:12 +07:00
|
|
|
static void __init harmony_init(void)
|
|
|
|
{
|
ARM: dt: tegra: harmony: add regulators
Harmony uses a TPS6586x regulator. Instantiate this, and hook up a
couple of fixed GPIO-controlled regulators too.
Based on Ventana regulator patch by Stephen Warren <swarren@nvidia.com>
and converted to Harmony.
swarren made the following changes:
* Added ldo0 regulator configuration to device tree, and updated
board-harmony-pcie.c for the new regulator name.
* Fixed vdd_1v05's voltage from 10.5V to 1.05V.
* Modified board-harmony-pcie.c to obtain the en_vdd_1v05 GPIO number at
run-time from device tree instead of hard-coding it.
* Removed board-harmony{-power.c,.h} now that they're unused.
* Disabled vdd_1v05 regulator; the code in board-harmony-pcie.c hijacks
this GPIO for now. This will be fixed when the PCIe driver is re-
written as a driver. The code can't regulator_get("vdd_1v05") right
now, because the vdd_1v05 regulator's probe gets deferred due to its
supply being the PMIC, which gets probed after the regulator the first
time around, and this dependency is only resolved by repeated probing,
which happens when deferred_probe_initcall() is called, which happens
in a late initcall, whose runtime order relative to harmony_pcie_init()
is undefined, since that's also called from a late initcall.
* Removed unused harmony_pcie_initcall().
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2012-08-17 03:59:59 +07:00
|
|
|
#ifdef CONFIG_TEGRA_PCI
|
2012-05-03 04:47:12 +07:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = harmony_pcie_init();
|
|
|
|
if (ret)
|
|
|
|
pr_err("harmony_pcie_init() failed: %d\n", ret);
|
|
|
|
#endif
|
2012-08-04 04:24:38 +07:00
|
|
|
}
|
2012-05-03 04:47:12 +07:00
|
|
|
|
2012-05-03 05:05:44 +07:00
|
|
|
static void __init paz00_init(void)
|
|
|
|
{
|
2013-02-14 00:15:50 +07:00
|
|
|
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
|
|
|
|
tegra_paz00_wifikill_init();
|
2012-05-03 05:05:44 +07:00
|
|
|
}
|
|
|
|
|
2012-05-03 02:43:26 +07:00
|
|
|
static struct {
|
|
|
|
char *machine;
|
|
|
|
void (*init)(void);
|
|
|
|
} board_init_funcs[] = {
|
|
|
|
{ "compulab,trimslice", trimslice_init },
|
2012-05-03 04:47:12 +07:00
|
|
|
{ "nvidia,harmony", harmony_init },
|
2012-05-03 05:05:44 +07:00
|
|
|
{ "compal,paz00", paz00_init },
|
2012-05-03 02:43:26 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
static void __init tegra_dt_init_late(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
tegra_init_late();
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
|
|
|
|
if (of_machine_is_compatible(board_init_funcs[i].machine)) {
|
|
|
|
board_init_funcs[i].init();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-14 00:15:50 +07:00
|
|
|
static const char * const tegra_dt_board_compat[] = {
|
|
|
|
"nvidia,tegra114",
|
|
|
|
"nvidia,tegra30",
|
2012-02-28 08:26:16 +07:00
|
|
|
"nvidia,tegra20",
|
2011-07-20 06:26:54 +07:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2013-02-14 00:15:50 +07:00
|
|
|
DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
|
2011-07-20 06:26:54 +07:00
|
|
|
.map_io = tegra_map_common_io,
|
2011-09-08 19:15:22 +07:00
|
|
|
.smp = smp_ops(tegra_smp_ops),
|
2013-02-14 00:15:48 +07:00
|
|
|
.init_early = tegra_init_early,
|
2011-11-30 08:29:19 +07:00
|
|
|
.init_irq = tegra_dt_init_irq,
|
2012-10-24 00:52:53 +07:00
|
|
|
.init_time = clocksource_of_init,
|
2011-07-20 06:26:54 +07:00
|
|
|
.init_machine = tegra_dt_init,
|
2012-05-03 02:43:26 +07:00
|
|
|
.init_late = tegra_dt_init_late,
|
2011-11-05 15:48:33 +07:00
|
|
|
.restart = tegra_assert_system_reset,
|
2013-02-14 00:15:50 +07:00
|
|
|
.dt_compat = tegra_dt_board_compat,
|
2011-07-20 06:26:54 +07:00
|
|
|
MACHINE_END
|