1 /* $NetBSD: tegra_platform.c,v 1.11 2018/04/01 04:35:04 ryo Exp $ */ 2 3 /*- 4 * Copyright (c) 2017 Jared D. McNeill <jmcneill@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_tegra.h" 30 #include "opt_multiprocessor.h" 31 #include "opt_fdt_arm.h" 32 33 #include "ukbd.h" 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: tegra_platform.c,v 1.11 2018/04/01 04:35:04 ryo Exp $"); 37 38 #include <sys/param.h> 39 #include <sys/bus.h> 40 #include <sys/cpu.h> 41 #include <sys/device.h> 42 #include <sys/termios.h> 43 44 #include <dev/fdt/fdtvar.h> 45 46 #include <uvm/uvm_extern.h> 47 48 #include <machine/bootconfig.h> 49 #include <arm/cpufunc.h> 50 51 #include <arm/nvidia/tegra_reg.h> 52 #include <arm/nvidia/tegra_var.h> 53 #include <arm/nvidia/tegra_platform.h> 54 55 #include <arm/fdt/arm_fdtvar.h> 56 57 #if NUKBD > 0 58 #include <dev/usb/ukbdvar.h> 59 #endif 60 61 #include <dev/ic/ns16550reg.h> 62 #include <dev/ic/comreg.h> 63 64 #define PLLP_OUT0_FREQ 408000000 65 66 void tegra_platform_early_putchar(char); 67 68 static const struct pmap_devmap * 69 tegra_platform_devmap(void) 70 { 71 static const struct pmap_devmap devmap[] = { 72 DEVMAP_ENTRY(TEGRA_HOST1X_VBASE, 73 TEGRA_HOST1X_BASE, 74 TEGRA_HOST1X_SIZE), 75 DEVMAP_ENTRY(TEGRA_PPSB_VBASE, 76 TEGRA_PPSB_BASE, 77 TEGRA_PPSB_SIZE), 78 DEVMAP_ENTRY(TEGRA_APB_VBASE, 79 TEGRA_APB_BASE, 80 TEGRA_APB_SIZE), 81 DEVMAP_ENTRY(TEGRA_AHB_A2_VBASE, 82 TEGRA_AHB_A2_BASE, 83 TEGRA_AHB_A2_SIZE), 84 DEVMAP_ENTRY_END 85 }; 86 87 return devmap; 88 } 89 90 static void 91 tegra124_platform_bootstrap(void) 92 { 93 tegra_bootstrap(); 94 95 #ifdef MULTIPROCESSOR 96 tegra124_mpinit(); 97 #endif 98 } 99 100 static void 101 tegra210_platform_bootstrap(void) 102 { 103 tegra_bootstrap(); 104 105 #ifdef MULTIPROCESSOR 106 tegra210_mpinit(); 107 #endif 108 } 109 110 static void 111 tegra_platform_init_attach_args(struct fdt_attach_args *faa) 112 { 113 extern struct bus_space arm_generic_bs_tag; 114 extern struct bus_space arm_generic_a4x_bs_tag; 115 extern struct arm32_bus_dma_tag arm_generic_dma_tag; 116 117 faa->faa_bst = &arm_generic_bs_tag; 118 faa->faa_a4x_bst = &arm_generic_a4x_bs_tag; 119 faa->faa_dmat = &arm_generic_dma_tag; 120 } 121 122 void 123 tegra_platform_early_putchar(char c) 124 { 125 #ifdef CONSADDR 126 #define CONSADDR_VA (CONSADDR - TEGRA_APB_BASE + TEGRA_APB_VBASE) 127 128 volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 129 (volatile uint32_t *)CONSADDR_VA : 130 (volatile uint32_t *)CONSADDR; 131 132 while ((uartaddr[com_lsr] & LSR_TXRDY) == 0) 133 ; 134 135 uartaddr[com_data] = c; 136 #endif 137 } 138 139 static void 140 tegra_platform_device_register(device_t self, void *aux) 141 { 142 prop_dictionary_t dict = device_properties(self); 143 144 if (device_is_a(self, "tegrafb") && 145 match_bootconf_option(boot_args, "console", "fb")) { 146 prop_dictionary_set_bool(dict, "is_console", true); 147 #if NUKBD > 0 148 ukbd_cnattach(); 149 #endif 150 } 151 152 if (device_is_a(self, "tegradrm")) { 153 const char *video = get_bootconf_string(boot_args, "video"); 154 if (video) 155 prop_dictionary_set_cstring(dict, "HDMI-A-1", video); 156 if (match_bootconf_option(boot_args, "hdmi.forcemode", "dvi")) 157 prop_dictionary_set_bool(dict, "force-dvi", true); 158 } 159 160 if (device_is_a(self, "tegracec")) 161 prop_dictionary_set_cstring(dict, "hdmi-device", "tegradrm0"); 162 163 if (device_is_a(self, "nouveau")) { 164 const char *config = get_bootconf_string(boot_args, 165 "nouveau.config"); 166 if (config) 167 prop_dictionary_set_cstring(dict, "config", config); 168 const char *debug = get_bootconf_string(boot_args, 169 "nouveau.debug"); 170 if (debug) 171 prop_dictionary_set_cstring(dict, "debug", debug); 172 } 173 174 if (device_is_a(self, "tegrapcie")) { 175 const char * const jetsontk1_compat[] = { 176 "nvidia,jetson-tk1", NULL 177 }; 178 const int phandle = OF_peer(0); 179 if (of_match_compatible(phandle, jetsontk1_compat)) { 180 /* rfkill GPIO at GPIO X7 */ 181 struct tegra_gpio_pin *pin = 182 tegra_gpio_acquire("X7", GPIO_PIN_OUTPUT); 183 if (pin) 184 tegra_gpio_write(pin, 1); 185 } 186 } 187 } 188 189 static void 190 tegra_platform_reset(void) 191 { 192 tegra_pmc_reset(); 193 } 194 195 static void 196 tegra_platform_delay(u_int us) 197 { 198 tegra_timer_delay(us); 199 } 200 201 static u_int 202 tegra_platform_uart_freq(void) 203 { 204 return PLLP_OUT0_FREQ; 205 } 206 207 static const struct arm_platform tegra124_platform = { 208 .devmap = tegra_platform_devmap, 209 .bootstrap = tegra124_platform_bootstrap, 210 .init_attach_args = tegra_platform_init_attach_args, 211 .early_putchar = tegra_platform_early_putchar, 212 .device_register = tegra_platform_device_register, 213 .reset = tegra_platform_reset, 214 .delay = tegra_platform_delay, 215 .uart_freq = tegra_platform_uart_freq, 216 }; 217 218 ARM_PLATFORM(tegra124, "nvidia,tegra124", &tegra124_platform); 219 220 static const struct arm_platform tegra210_platform = { 221 .devmap = tegra_platform_devmap, 222 .bootstrap = tegra210_platform_bootstrap, 223 .init_attach_args = tegra_platform_init_attach_args, 224 .early_putchar = tegra_platform_early_putchar, 225 .device_register = tegra_platform_device_register, 226 .reset = tegra_platform_reset, 227 .delay = tegra_platform_delay, 228 .uart_freq = tegra_platform_uart_freq, 229 }; 230 231 ARM_PLATFORM(tegra210, "nvidia,tegra210", &tegra210_platform); 232