/* * arch/arm64/mach-tegra/board-t210ref.c * * Copyright (c) 2013-2016, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 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. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "board.h" #include "board-panel.h" #include "board-common.h" #include "board-touch-raydium.h" #include "board-touch-maxim_sti.h" #include #include #include "devices.h" #include "gpio-names.h" #include "iomap.h" #include "pm.h" #include "tegra-board-id.h" #include "tegra-of-dev-auxdata.h" #include #include #include "board-t210.h" #ifdef CONFIG_CAN_MCP251X #include #define CAN_GPIO_IRQ_MCP251x_SPI TEGRA_GPIO_PV6 static struct mcp251x_platform_data mcp251x_info = { .oscillator_frequency = 8 * 1000 * 1000, /* CAN SPI click 5V has a 8MHz crystal */ .irq_flags = IRQF_TRIGGER_FALLING|IRQF_ONESHOT, /* This is also defined in the mcp251x driver: can be ommited */ .board_specific_setup = NULL, /* We don't have a board specific setup */ .power_enable = NULL, /* We don't want any power enable function */ .transceiver_enable = NULL, /* We don't want any transceiver enable function */ }; struct spi_board_info mcp251x_spi_board[1] = { { .modalias = "mcp2515", /* (or mcp2510) used chip controller */ .platform_data = &mcp251x_info, /* reference to the mcp251x_platform_data mcp251x_info */ .max_speed_hz = 8 * 1000 * 1000, /* max speed of the used chip */ .chip_select = 0, /* the spi cs usage*/ .bus_num = 1, .mode = SPI_MODE_0, }, }; static int __init mcp251x_init(void) { mcp251x_spi_board[0].irq = gpio_to_irq(CAN_GPIO_IRQ_MCP251x_SPI); // #define CAN_GPIO_IRQ_MCP251x_SPI TEGRA_GPIO_PK2 spi_register_board_info(mcp251x_spi_board, ARRAY_SIZE(mcp251x_spi_board)); pr_info("mcp251x_init\n"); return 0; } #endif #define UTMI1_PORT_OWNER_XUSB 0x1 static struct tegra_usb_platform_data tegra_udc_pdata; static struct tegra_usb_otg_data tegra_otg_pdata; static void t210ref_usb_init(void) { int usb_port_owner_info = tegra_get_usb_port_owner_info(); if (!(usb_port_owner_info & UTMI1_PORT_OWNER_XUSB)) { tegra_otg_pdata.is_xhci = false; tegra_udc_pdata.u_data.dev.is_xhci = false; } else { tegra_otg_pdata.is_xhci = true; tegra_udc_pdata.u_data.dev.is_xhci = true; } } static struct of_dev_auxdata t210ref_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra210-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), OF_DEV_AUXDATA("nvidia,tegra210-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), OF_DEV_AUXDATA("nvidia,tegra210-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL), OF_DEV_AUXDATA("nvidia,tegra210-sdhci", TEGRA_SDMMC4_BASE, "sdhci-tegra.3", NULL), OF_DEV_AUXDATA("nvidia,tegra210-udc", TEGRA_USB_BASE, "tegra-udc.0", &tegra_udc_pdata.u_data.dev), OF_DEV_AUXDATA("nvidia,tegra132-otg", TEGRA_USB_BASE, "tegra-otg", &tegra_otg_pdata), OF_DEV_AUXDATA("nvidia,tegra132-ehci", TEGRA_USB_BASE, "tegra-ehci.0", NULL), OF_DEV_AUXDATA("nvidia,tegra210-usb-cd", TEGRA_XUSB_PADCTL_BASE, "tegra-usb-cd", NULL), OF_DEV_AUXDATA("nvidia,tegra132-ehci", 0x7d004000, "tegra-ehci.1", NULL), OF_DEV_AUXDATA("nvidia,tegra210-host1x", TEGRA_HOST1X_BASE, "host1x", NULL), OF_DEV_AUXDATA("nvidia,tegra210-gm20b", TEGRA_GK20A_BAR0_BASE, "gpu.0", NULL), OF_DEV_AUXDATA("nvidia,tegra210-nvenc", TEGRA_NVENC_BASE, "msenc", NULL), OF_DEV_AUXDATA("nvidia,tegra210-vi", TEGRA_VI_BASE, "vi", NULL), OF_DEV_AUXDATA("nvidia,tegra210-isp", TEGRA_ISP_BASE, "isp.0", NULL), OF_DEV_AUXDATA("nvidia,tegra210-isp", TEGRA_ISPB_BASE, "isp.1", NULL), OF_DEV_AUXDATA("nvidia,tegra210-tsec", TEGRA_TSEC_BASE, "tsec", NULL), OF_DEV_AUXDATA("nvidia,tegra210-tsec", TEGRA_TSECB_BASE, "tsecb", NULL), OF_DEV_AUXDATA("nvidia,tegra210-vic", TEGRA_VIC_BASE, "vic03", NULL), OF_DEV_AUXDATA("nvidia,tegra210-se", 0x70012000, "tegra21-se", NULL), OF_DEV_AUXDATA("nvidia,tegra210-dtv", 0x7000c300, "dtv", NULL), OF_DEV_AUXDATA("nvidia,tegra210-nvdec", TEGRA_NVDEC_BASE, "nvdec", NULL), OF_DEV_AUXDATA("nvidia,tegra210-nvjpg", TEGRA_NVJPG_BASE, "nvjpg", NULL), OF_DEV_AUXDATA("nvidia,tegra210-axbar", TEGRA_AXBAR_BASE, "tegra210-axbar", NULL), OF_DEV_AUXDATA("nvidia,tegra210-adma", TEGRA_ADMA_BASE, "tegra210-adma", NULL), OF_DEV_AUXDATA("nvidia,tegra124-apbdma", 0x60020000, "tegra-apbdma", NULL), OF_DEV_AUXDATA("nvidia,tegra210-qspi", 0x70410000, "qspi", NULL), OF_DEV_AUXDATA("nvidia,tegra210-ahci-sata", 0x70021000, "tegra-sata.0", NULL), OF_DEV_AUXDATA("nvidia,tegra210-adsp-audio", 0, "adsp_audio.3", NULL), OF_DEV_AUXDATA("nvidia,tegra210-efuse", TEGRA_FUSE_BASE, "tegra-fuse", NULL), OF_DEV_AUXDATA("linux,spdif-dit", 0, "spdif-dit.0", NULL), OF_DEV_AUXDATA("linux,spdif-dit", 1, "spdif-dit.1", NULL), OF_DEV_AUXDATA("linux,spdif-dit", 2, "spdif-dit.2", NULL), OF_DEV_AUXDATA("linux,spdif-dit", 3, "spdif-dit.3", NULL), OF_DEV_AUXDATA("linux,spdif-dit", 4, "spdif-dit.4", NULL), OF_DEV_AUXDATA("nvidia,tegra210-xhci", 0x70090000, "tegra-xhci", NULL), OF_DEV_AUXDATA("nvidia,tegra210-xudc", 0x700D0000, "tegra-xudc", NULL), OF_DEV_AUXDATA("nvidia,tegra210-camera", 0, "pcl-generic", NULL), OF_DEV_AUXDATA("nvidia,tegra210-dc", TEGRA_DISPLAY_BASE, "tegradc.0", NULL), OF_DEV_AUXDATA("nvidia,tegra210-dc", TEGRA_DISPLAY2_BASE, "tegradc.1", NULL), OF_DEV_AUXDATA("pwm-backlight", 0, "pwm-backlight", NULL), #ifdef CONFIG_TEGRA_CEC_SUPPORT OF_DEV_AUXDATA("nvidia,tegra210-cec", 0x70015000, "tegra_cec", NULL), #endif OF_DEV_AUXDATA("nvidia,tegra-audio-rt5639", 0x0, "tegra-snd-rt5639", NULL), OF_DEV_AUXDATA("nvidia,icera-i500", 0, "tegra_usb_modem_power", NULL), OF_DEV_AUXDATA("raydium,rm_ts_spidev", 0, "rm_ts_spidev", NULL), OF_DEV_AUXDATA("nvidia,tegra30-hda", 0x70030000, "tegra30-hda", NULL), OF_DEV_AUXDATA("nvidia,ptm", 0x72010000, "ptm", NULL), {} }; static void __init tegra_t210ref_early_init(void) { if (!tegra_platform_is_fpga()) { tegra_clk_init_from_dt("t210-clk-init-table"); tegra_clk_verify_parents(); } if (of_machine_is_compatible("nvidia,e2141")) tegra_soc_device_init("e2141"); else if (of_machine_is_compatible("nvidia,e2220")) tegra_soc_device_init("e2220"); else if (of_machine_is_compatible("nvidia,e2190")) tegra_soc_device_init("e2190"); else if (of_machine_is_compatible("nvidia,grenada")) tegra_soc_device_init("grenada"); else if (of_machine_is_compatible("nvidia,loki-e")) tegra_soc_device_init("loki_e"); else if (of_machine_is_compatible("nvidia,foster-e")) tegra_soc_device_init("foster_e"); else if (of_machine_is_compatible("nvidia,jetson-e")) tegra_soc_device_init("jetson_e"); else if (of_machine_is_compatible("nvidia,jetson-cv")) tegra_soc_device_init("jetson_cv"); else if (of_machine_is_compatible("nvidia,he2290")) tegra_soc_device_init("he2290"); } #ifdef CONFIG_PM_SLEEP static struct tegra_suspend_platform_data t210ref_suspend_data = { .cpu_timer = 1700, .cpu_off_timer = 300, .suspend_mode = TEGRA_SUSPEND_LP0, .core_timer = 0x61e1, .core_off_timer = 1350, .cpu_suspend_freq = 204000, .corereq_high = true, .sysclkreq_high = true, }; static int __init t210ref_suspend_init(void) { tegra_init_suspend(&t210ref_suspend_data); return 0; } #endif static void __init tegra_t210ref_late_init(void) { struct board_info board_info; tegra_get_board_info(&board_info); pr_info("board_info: id:sku:fab:major:minor = 0x%04x:0x%04x:0x%02x:0x%02x:0x%02x\n", board_info.board_id, board_info.sku, board_info.fab, board_info.major_revision, board_info.minor_revision); t210ref_usb_init(); tegra_io_dpd_init(); #ifdef CONFIG_PM_SLEEP /* FIXME: Assumed all t210ref platforms have sdhci DT support */ t210ref_suspend_init(); #endif tegra21_emc_init(); isomgr_init(); #ifdef CONFIG_CAN_MCP251X mcp251x_init(); #endif /* put PEX pads into DPD mode to save additional power */ t210ref_camera_init(); } static void __init tegra_t210ref_init_early(void) { tegra21x_init_early(); } static int tegra_t210ref_notifier_call(struct notifier_block *nb, unsigned long event, void *data) { #ifndef CONFIG_TEGRA_HDMI_PRIMARY struct device *dev = data; #endif switch (event) { case BUS_NOTIFY_BIND_DRIVER: #ifndef CONFIG_TEGRA_HDMI_PRIMARY if (dev->of_node) { if (of_device_is_compatible(dev->of_node, "pwm-backlight")) { tegra_pwm_bl_ops_register(dev); } } #endif break; default: break; } return NOTIFY_DONE; } static int tegra_t210ref_i2c_notifier_call(struct notifier_block *nb, unsigned long event, void *data) { #ifndef CONFIG_TEGRA_HDMI_PRIMARY struct device *dev = data; #endif switch (event) { case BUS_NOTIFY_BIND_DRIVER: #ifndef CONFIG_TEGRA_HDMI_PRIMARY if (dev->of_node) { if (of_device_is_compatible(dev->of_node, "ti,lp8550") || of_device_is_compatible(dev->of_node, "ti,lp8551") || of_device_is_compatible(dev->of_node, "ti,lp8552") || of_device_is_compatible(dev->of_node, "ti,lp8553") || of_device_is_compatible(dev->of_node, "ti,lp8554") || of_device_is_compatible(dev->of_node, "ti,lp8555") || of_device_is_compatible(dev->of_node, "ti,lp8556") || of_device_is_compatible(dev->of_node, "ti,lp8557")) { ti_lp855x_bl_ops_register(dev); } } #endif break; default: break; } return NOTIFY_DONE; } static struct notifier_block platform_nb = { .notifier_call = tegra_t210ref_notifier_call, }; static struct notifier_block i2c_nb = { .notifier_call = tegra_t210ref_i2c_notifier_call, }; static void __init tegra_t210ref_dt_init(void) { unsigned long pinmux_clamp = readl(IO_ADDRESS(0x70000040)); /* Check for the PINMUX CLAMP Settings */ if (pinmux_clamp & 1) pr_warn("WARN: pinmux CLAMP_INPUTS_WHEN_TRISTATED: enabled\n"); else pr_warn("INFO: pinmux CLAMP_INPUTS_WHEN_TRISTATED: disabled\n"); regulator_has_full_constraints(); #ifndef CONFIG_TEGRA_HDMI_PRIMARY /* * In t210ref, zero display_board_id is considered to * jdi 1440x810 5.8" one. */ tegra_set_fixed_panel_ops(true, &dsi_j_1440_810_5_8_ops, "j,1440-810-5-8"); tegra_set_fixed_pwm_bl_ops(dsi_j_1440_810_5_8_ops.pwm_bl_ops); #endif bus_register_notifier(&platform_bus_type, &platform_nb); bus_register_notifier(&i2c_bus_type, &i2c_nb); tegra_t210ref_early_init(); of_platform_populate(NULL, of_default_bus_match_table, t210ref_auxdata_lookup, &platform_bus); tegra_t210ref_late_init(); } static void __init tegra_t210ref_reserve(void) { #if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM) || \ defined(CONFIG_TEGRA_NO_CARVEOUT) ulong carveout_size = 0; #else ulong carveout_size = SZ_1G; #endif ulong vpr_size = 364 * SZ_1M; if (of_flat_dt_is_compatible(of_get_flat_dt_root(), "nvidia,foster-e")) vpr_size = 672 * SZ_1M; tegra_reserve4(carveout_size, 0, 0, vpr_size); } static const char * const t210ref_dt_board_compat[] = { "nvidia,e2220", "nvidia,e2190", "nvidia,e2141", "nvidia,grenada", "nvidia,loki-e", "nvidia,foster-e", "nvidia,jetson-e", "nvidia,jetson-cv", "nvidia,he2290", NULL }; DT_MACHINE_START(T210REF, "t210ref") .atag_offset = 0x100, .map_io = tegra_map_common_io, .reserve = tegra_t210ref_reserve, .init_early = tegra_t210ref_init_early, .init_time = clocksource_of_init, .init_machine = tegra_t210ref_dt_init, .dt_compat = t210ref_dt_board_compat, .init_late = tegra_init_late, MACHINE_END