Home | History | Annotate | Line # | Download | only in nvidia
tegra_platform.c revision 1.17
      1 /* $NetBSD: tegra_platform.c,v 1.17 2018/10/18 09:01:53 skrll Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2017 Jared D. McNeill <jmcneill (at) invisible.ca>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include "opt_arm_debug.h"
     30 #include "opt_console.h"
     31 #include "opt_multiprocessor.h"
     32 #include "opt_tegra.h"
     33 
     34 #include "ukbd.h"
     35 
     36 #include <sys/cdefs.h>
     37 __KERNEL_RCSID(0, "$NetBSD: tegra_platform.c,v 1.17 2018/10/18 09:01:53 skrll Exp $");
     38 
     39 #include <sys/param.h>
     40 #include <sys/bus.h>
     41 #include <sys/cpu.h>
     42 #include <sys/device.h>
     43 #include <sys/termios.h>
     44 
     45 #include <dev/fdt/fdtvar.h>
     46 
     47 #include <uvm/uvm_extern.h>
     48 
     49 #include <machine/bootconfig.h>
     50 #include <arm/cpufunc.h>
     51 
     52 #include <arm/nvidia/tegra_reg.h>
     53 #include <arm/nvidia/tegra_var.h>
     54 #include <arm/nvidia/tegra_platform.h>
     55 
     56 #include <arm/fdt/arm_fdtvar.h>
     57 
     58 #include <arm/arm/psci.h>
     59 #include <arm/fdt/psci_fdtvar.h>
     60 
     61 #if NUKBD > 0
     62 #include <dev/usb/ukbdvar.h>
     63 #endif
     64 
     65 #include <dev/ic/ns16550reg.h>
     66 #include <dev/ic/comreg.h>
     67 
     68 #define	PLLP_OUT0_FREQ	408000000
     69 
     70 void tegra_platform_early_putchar(char);
     71 
     72 static const struct pmap_devmap *
     73 tegra_platform_devmap(void)
     74 {
     75 	static const struct pmap_devmap devmap[] = {
     76 		DEVMAP_ENTRY(TEGRA_HOST1X_VBASE,
     77 			     TEGRA_HOST1X_BASE,
     78 			     TEGRA_HOST1X_SIZE),
     79 		DEVMAP_ENTRY(TEGRA_PPSB_VBASE,
     80 			     TEGRA_PPSB_BASE,
     81 			     TEGRA_PPSB_SIZE),
     82 		DEVMAP_ENTRY(TEGRA_APB_VBASE,
     83 			     TEGRA_APB_BASE,
     84 			     TEGRA_APB_SIZE),
     85 		DEVMAP_ENTRY(TEGRA_AHB_A2_VBASE,
     86 			     TEGRA_AHB_A2_BASE,
     87 			     TEGRA_AHB_A2_SIZE),
     88 		DEVMAP_ENTRY_END
     89 	};
     90 
     91 	return devmap;
     92 }
     93 
     94 #if defined(SOC_TEGRA124)
     95 static void
     96 tegra124_platform_bootstrap(void)
     97 {
     98 #ifdef MULTIPROCESSOR
     99 	arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU);
    100 #endif
    101 
    102 	tegra_bootstrap();
    103 }
    104 #endif
    105 
    106 #if defined(SOC_TEGRA210)
    107 static void
    108 tegra210_platform_bootstrap(void)
    109 {
    110 
    111 	tegra_bootstrap();
    112 }
    113 
    114 static void
    115 tegra210_platform_mpstart(void)
    116 {
    117 
    118 #if defined(MULTIPROCESSOR) && defined(__aarch64__)
    119 	arm_fdt_cpu_bootstrap();
    120 #endif
    121 }
    122 #endif
    123 
    124 static void
    125 tegra_platform_init_attach_args(struct fdt_attach_args *faa)
    126 {
    127 	extern struct bus_space arm_generic_bs_tag;
    128 	extern struct bus_space arm_generic_a4x_bs_tag;
    129 	extern struct arm32_bus_dma_tag arm_generic_dma_tag;
    130 
    131 	faa->faa_bst = &arm_generic_bs_tag;
    132 	faa->faa_a4x_bst = &arm_generic_a4x_bs_tag;
    133 	faa->faa_dmat = &arm_generic_dma_tag;
    134 }
    135 
    136 void
    137 tegra_platform_early_putchar(char c)
    138 {
    139 #ifdef CONSADDR
    140 #define CONSADDR_VA	(CONSADDR - TEGRA_APB_BASE + TEGRA_APB_VBASE)
    141 
    142 	volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
    143 	    (volatile uint32_t *)CONSADDR_VA :
    144 	    (volatile uint32_t *)CONSADDR;
    145 
    146 	while ((uartaddr[com_lsr] & LSR_TXRDY) == 0)
    147 		;
    148 
    149 	uartaddr[com_data] = c;
    150 #endif
    151 }
    152 
    153 static void
    154 tegra_platform_device_register(device_t self, void *aux)
    155 {
    156 	prop_dictionary_t dict = device_properties(self);
    157 
    158 	if (device_is_a(self, "tegrafb") &&
    159 	    match_bootconf_option(boot_args, "console", "fb")) {
    160 		prop_dictionary_set_bool(dict, "is_console", true);
    161 #if NUKBD > 0
    162 		ukbd_cnattach();
    163 #endif
    164 	}
    165 
    166 	if (device_is_a(self, "tegradrm")) {
    167 		const char *video = get_bootconf_string(boot_args, "video");
    168 		if (video)
    169 			prop_dictionary_set_cstring(dict, "HDMI-A-1", video);
    170 		if (match_bootconf_option(boot_args, "hdmi.forcemode", "dvi"))
    171 			prop_dictionary_set_bool(dict, "force-dvi", true);
    172 	}
    173 
    174 	if (device_is_a(self, "tegracec"))
    175 		prop_dictionary_set_cstring(dict, "hdmi-device", "tegradrm0");
    176 
    177 	if (device_is_a(self, "nouveau")) {
    178 		const char *config = get_bootconf_string(boot_args,
    179 		    "nouveau.config");
    180 		if (config)
    181 			prop_dictionary_set_cstring(dict, "config", config);
    182 		const char *debug = get_bootconf_string(boot_args,
    183 		    "nouveau.debug");
    184 		if (debug)
    185 			prop_dictionary_set_cstring(dict, "debug", debug);
    186 	}
    187 
    188 	if (device_is_a(self, "tegrapcie")) {
    189 		const char * const jetsontk1_compat[] = {
    190 		    "nvidia,jetson-tk1", NULL
    191 		};
    192 		const int phandle = OF_peer(0);
    193 		if (of_match_compatible(phandle, jetsontk1_compat)) {
    194 			/* rfkill GPIO at GPIO X7 */
    195 			struct tegra_gpio_pin *pin =
    196 			    tegra_gpio_acquire("X7", GPIO_PIN_OUTPUT);
    197 			if (pin)
    198 				tegra_gpio_write(pin, 1);
    199 		}
    200 	}
    201 }
    202 
    203 static void
    204 tegra_platform_reset(void)
    205 {
    206 	tegra_pmc_reset();
    207 }
    208 
    209 static void
    210 tegra_platform_delay(u_int us)
    211 {
    212 	tegra_timer_delay(us);
    213 }
    214 
    215 static u_int
    216 tegra_platform_uart_freq(void)
    217 {
    218 	return PLLP_OUT0_FREQ;
    219 }
    220 
    221 #if defined(SOC_TEGRA124)
    222 static const struct arm_platform tegra124_platform = {
    223 	.ap_devmap = tegra_platform_devmap,
    224 	.ap_bootstrap = tegra124_platform_bootstrap,
    225 	.ap_init_attach_args = tegra_platform_init_attach_args,
    226 	.ap_early_putchar = tegra_platform_early_putchar,
    227 	.ap_device_register = tegra_platform_device_register,
    228 	.ap_reset = tegra_platform_reset,
    229 	.ap_delay = tegra_platform_delay,
    230 	.ap_uart_freq = tegra_platform_uart_freq,
    231 	.ap_mpstart = tegra124_mpstart,
    232 };
    233 
    234 ARM_PLATFORM(tegra124, "nvidia,tegra124", &tegra124_platform);
    235 #endif
    236 
    237 #if defined(SOC_TEGRA210)
    238 static const struct arm_platform tegra210_platform = {
    239 	.ap_devmap = tegra_platform_devmap,
    240 	.ap_bootstrap = tegra210_platform_bootstrap,
    241 	.ap_init_attach_args = tegra_platform_init_attach_args,
    242 	.ap_early_putchar = tegra_platform_early_putchar,
    243 	.ap_device_register = tegra_platform_device_register,
    244 	.ap_reset = tegra_platform_reset,
    245 	.ap_delay = tegra_platform_delay,
    246 	.ap_uart_freq = tegra_platform_uart_freq,
    247 	.ap_mpstart = tegra210_platform_mpstart,
    248 };
    249 
    250 ARM_PLATFORM(tegra210, "nvidia,tegra210", &tegra210_platform);
    251 #endif
    252