1 1.18 thorpej /* $NetBSD: rk_platform.c,v 1.18 2025/09/06 21:02:40 thorpej Exp $ */ 2 1.1 jmcneill 3 1.1 jmcneill /*- 4 1.15 jmcneill * Copyright (c) 2018,2021 Jared McNeill <jmcneill (at) invisible.ca> 5 1.1 jmcneill * All rights reserved. 6 1.1 jmcneill * 7 1.1 jmcneill * Redistribution and use in source and binary forms, with or without 8 1.1 jmcneill * modification, are permitted provided that the following conditions 9 1.1 jmcneill * are met: 10 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright 11 1.1 jmcneill * notice, this list of conditions and the following disclaimer. 12 1.1 jmcneill * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 jmcneill * notice, this list of conditions and the following disclaimer in the 14 1.1 jmcneill * documentation and/or other materials provided with the distribution. 15 1.1 jmcneill * 16 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 jmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 jmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 jmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 jmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 1.1 jmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 1.1 jmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 1.1 jmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 1.1 jmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 jmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 jmcneill * SUCH DAMAGE. 27 1.1 jmcneill */ 28 1.1 jmcneill 29 1.1 jmcneill #include "opt_soc.h" 30 1.1 jmcneill #include "opt_multiprocessor.h" 31 1.5 skrll #include "opt_console.h" 32 1.1 jmcneill 33 1.1 jmcneill #include <sys/cdefs.h> 34 1.18 thorpej __KERNEL_RCSID(0, "$NetBSD: rk_platform.c,v 1.18 2025/09/06 21:02:40 thorpej Exp $"); 35 1.1 jmcneill 36 1.1 jmcneill #include <sys/param.h> 37 1.1 jmcneill #include <sys/bus.h> 38 1.1 jmcneill #include <sys/cpu.h> 39 1.1 jmcneill #include <sys/device.h> 40 1.1 jmcneill #include <sys/termios.h> 41 1.1 jmcneill 42 1.17 skrll #include <dev/fdt/fdtvar.h> 43 1.18 thorpej #include <dev/fdt/fdt_platform.h> 44 1.13 mrg 45 1.1 jmcneill #include <arm/fdt/arm_fdtvar.h> 46 1.1 jmcneill 47 1.1 jmcneill #include <uvm/uvm_extern.h> 48 1.1 jmcneill 49 1.1 jmcneill #include <machine/bootconfig.h> 50 1.1 jmcneill #include <arm/cpufunc.h> 51 1.1 jmcneill 52 1.1 jmcneill #include <arm/cortex/gtmr_var.h> 53 1.1 jmcneill 54 1.1 jmcneill #include <dev/ic/ns16550reg.h> 55 1.1 jmcneill #include <dev/ic/comreg.h> 56 1.1 jmcneill 57 1.1 jmcneill #include <arm/arm/psci.h> 58 1.4 ryo #include <arm/fdt/psci_fdtvar.h> 59 1.1 jmcneill 60 1.1 jmcneill #include <libfdt.h> 61 1.1 jmcneill 62 1.1 jmcneill extern struct arm32_bus_dma_tag arm_generic_dma_tag; 63 1.1 jmcneill extern struct bus_space arm_generic_bs_tag; 64 1.1 jmcneill 65 1.1 jmcneill static void 66 1.1 jmcneill rk_platform_init_attach_args(struct fdt_attach_args *faa) 67 1.1 jmcneill { 68 1.1 jmcneill faa->faa_bst = &arm_generic_bs_tag; 69 1.1 jmcneill faa->faa_dmat = &arm_generic_dma_tag; 70 1.1 jmcneill } 71 1.1 jmcneill 72 1.1 jmcneill static void 73 1.1 jmcneill rk_platform_device_register(device_t self, void *aux) 74 1.1 jmcneill { 75 1.1 jmcneill } 76 1.1 jmcneill 77 1.1 jmcneill static void 78 1.1 jmcneill rk_platform_bootstrap(void) 79 1.1 jmcneill { 80 1.1 jmcneill void *fdt_data = __UNCONST(fdtbus_get_data()); 81 1.1 jmcneill 82 1.4 ryo arm_fdt_cpu_bootstrap(); 83 1.1 jmcneill 84 1.1 jmcneill const int chosen_off = fdt_path_offset(fdt_data, "/chosen"); 85 1.1 jmcneill if (chosen_off < 0) 86 1.1 jmcneill return; 87 1.1 jmcneill 88 1.1 jmcneill if (match_bootconf_option(boot_args, "console", "fb")) { 89 1.1 jmcneill const int framebuffer_off = 90 1.1 jmcneill fdt_path_offset(fdt_data, "/chosen/framebuffer"); 91 1.1 jmcneill if (framebuffer_off >= 0) { 92 1.1 jmcneill const char *status = fdt_getprop(fdt_data, 93 1.1 jmcneill framebuffer_off, "status", NULL); 94 1.1 jmcneill if (status == NULL || strncmp(status, "ok", 2) == 0) { 95 1.1 jmcneill fdt_setprop_string(fdt_data, chosen_off, 96 1.1 jmcneill "stdout-path", "/chosen/framebuffer"); 97 1.1 jmcneill } 98 1.1 jmcneill } 99 1.1 jmcneill } else if (match_bootconf_option(boot_args, "console", "serial")) { 100 1.1 jmcneill fdt_setprop_string(fdt_data, chosen_off, 101 1.1 jmcneill "stdout-path", "serial0:115200n8"); 102 1.1 jmcneill } 103 1.1 jmcneill } 104 1.1 jmcneill 105 1.15 jmcneill #ifdef SOC_RK3288 106 1.15 jmcneill 107 1.15 jmcneill #define RK3288_WDT_BASE 0xff800000 108 1.15 jmcneill #define RK3288_WDT_SIZE 0x10000 109 1.15 jmcneill 110 1.15 jmcneill #define RK3288_WDT_CR 0x0000 111 1.15 jmcneill #define RK3288_WDT_CR_WDT_EN __BIT(0) 112 1.15 jmcneill #define RK3288_WDT_TORR 0x0004 113 1.15 jmcneill #define RK3288_WDT_CRR 0x000c 114 1.15 jmcneill #define RK3288_WDT_MAGIC 0x76 115 1.15 jmcneill 116 1.15 jmcneill static bus_space_handle_t rk3288_wdt_bsh; 117 1.15 jmcneill 118 1.15 jmcneill #include <arm/rockchip/rk3288_platform.h> 119 1.15 jmcneill 120 1.15 jmcneill static const struct pmap_devmap * 121 1.15 jmcneill rk3288_platform_devmap(void) 122 1.15 jmcneill { 123 1.15 jmcneill static const struct pmap_devmap devmap[] = { 124 1.15 jmcneill DEVMAP_ENTRY(RK3288_CORE_VBASE, 125 1.15 jmcneill RK3288_CORE_PBASE, 126 1.15 jmcneill RK3288_CORE_SIZE), 127 1.15 jmcneill DEVMAP_ENTRY_END 128 1.15 jmcneill }; 129 1.15 jmcneill 130 1.15 jmcneill return devmap; 131 1.15 jmcneill } 132 1.15 jmcneill 133 1.15 jmcneill void rk3288_platform_early_putchar(char); 134 1.15 jmcneill 135 1.15 jmcneill void __noasan 136 1.15 jmcneill rk3288_platform_early_putchar(char c) 137 1.15 jmcneill { 138 1.15 jmcneill #ifdef CONSADDR 139 1.15 jmcneill #define CONSADDR_VA ((CONSADDR - RK3288_CORE_PBASE) + RK3288_CORE_VBASE) 140 1.15 jmcneill volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 141 1.15 jmcneill (volatile uint32_t *)CONSADDR_VA : 142 1.15 jmcneill (volatile uint32_t *)CONSADDR; 143 1.15 jmcneill 144 1.15 jmcneill while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0) 145 1.15 jmcneill ; 146 1.15 jmcneill 147 1.15 jmcneill uartaddr[com_data] = htole32(c); 148 1.15 jmcneill #undef CONSADDR_VA 149 1.15 jmcneill #endif 150 1.15 jmcneill } 151 1.15 jmcneill 152 1.15 jmcneill static void 153 1.15 jmcneill rk3288_platform_bootstrap(void) 154 1.15 jmcneill { 155 1.15 jmcneill bus_space_tag_t bst = &arm_generic_bs_tag; 156 1.15 jmcneill 157 1.15 jmcneill rk_platform_bootstrap(); 158 1.15 jmcneill bus_space_map(bst, RK3288_WDT_BASE, RK3288_WDT_SIZE, 0, &rk3288_wdt_bsh); 159 1.15 jmcneill } 160 1.15 jmcneill 161 1.15 jmcneill static void 162 1.15 jmcneill rk3288_platform_reset(void) 163 1.15 jmcneill { 164 1.15 jmcneill bus_space_tag_t bst = &arm_generic_bs_tag; 165 1.15 jmcneill 166 1.15 jmcneill bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_TORR, 0); 167 1.15 jmcneill bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_CRR, RK3288_WDT_MAGIC); 168 1.15 jmcneill for (;;) { 169 1.15 jmcneill bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_CR, RK3288_WDT_CR_WDT_EN); 170 1.15 jmcneill } 171 1.15 jmcneill } 172 1.15 jmcneill 173 1.15 jmcneill static u_int 174 1.15 jmcneill rk3288_platform_uart_freq(void) 175 1.15 jmcneill { 176 1.15 jmcneill return RK3288_UART_FREQ; 177 1.15 jmcneill } 178 1.15 jmcneill 179 1.17 skrll static const struct fdt_platform rk3288_platform = { 180 1.17 skrll .fp_devmap = rk3288_platform_devmap, 181 1.17 skrll .fp_bootstrap = rk3288_platform_bootstrap, 182 1.17 skrll .fp_init_attach_args = rk_platform_init_attach_args, 183 1.17 skrll .fp_device_register = rk_platform_device_register, 184 1.17 skrll .fp_reset = rk3288_platform_reset, 185 1.17 skrll .fp_delay = gtmr_delay, 186 1.17 skrll .fp_uart_freq = rk3288_platform_uart_freq, 187 1.17 skrll .fp_mpstart = arm_fdt_cpu_mpstart, 188 1.15 jmcneill }; 189 1.15 jmcneill 190 1.17 skrll FDT_PLATFORM(rk3288, "rockchip,rk3288", &rk3288_platform); 191 1.15 jmcneill #endif /* SOC_RK3288 */ 192 1.15 jmcneill 193 1.15 jmcneill 194 1.1 jmcneill #ifdef SOC_RK3328 195 1.1 jmcneill 196 1.1 jmcneill #include <arm/rockchip/rk3328_platform.h> 197 1.1 jmcneill 198 1.1 jmcneill static const struct pmap_devmap * 199 1.1 jmcneill rk3328_platform_devmap(void) 200 1.1 jmcneill { 201 1.1 jmcneill static const struct pmap_devmap devmap[] = { 202 1.1 jmcneill DEVMAP_ENTRY(RK3328_CORE_VBASE, 203 1.1 jmcneill RK3328_CORE_PBASE, 204 1.1 jmcneill RK3328_CORE_SIZE), 205 1.1 jmcneill DEVMAP_ENTRY_END 206 1.1 jmcneill }; 207 1.1 jmcneill 208 1.1 jmcneill return devmap; 209 1.1 jmcneill } 210 1.1 jmcneill 211 1.1 jmcneill void rk3328_platform_early_putchar(char); 212 1.1 jmcneill 213 1.9 skrll void __noasan 214 1.1 jmcneill rk3328_platform_early_putchar(char c) 215 1.1 jmcneill { 216 1.1 jmcneill #ifdef CONSADDR 217 1.1 jmcneill #define CONSADDR_VA ((CONSADDR - RK3328_CORE_PBASE) + RK3328_CORE_VBASE) 218 1.1 jmcneill volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 219 1.1 jmcneill (volatile uint32_t *)CONSADDR_VA : 220 1.1 jmcneill (volatile uint32_t *)CONSADDR; 221 1.1 jmcneill 222 1.1 jmcneill while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0) 223 1.1 jmcneill ; 224 1.1 jmcneill 225 1.1 jmcneill uartaddr[com_data] = htole32(c); 226 1.1 jmcneill #undef CONSADDR_VA 227 1.1 jmcneill #endif 228 1.1 jmcneill } 229 1.1 jmcneill 230 1.1 jmcneill static u_int 231 1.1 jmcneill rk3328_platform_uart_freq(void) 232 1.1 jmcneill { 233 1.1 jmcneill return RK3328_UART_FREQ; 234 1.1 jmcneill } 235 1.1 jmcneill 236 1.17 skrll static const struct fdt_platform rk3328_platform = { 237 1.17 skrll .fp_devmap = rk3328_platform_devmap, 238 1.17 skrll .fp_bootstrap = rk_platform_bootstrap, 239 1.17 skrll .fp_init_attach_args = rk_platform_init_attach_args, 240 1.17 skrll .fp_device_register = rk_platform_device_register, 241 1.17 skrll .fp_reset = psci_fdt_reset, 242 1.17 skrll .fp_delay = gtmr_delay, 243 1.17 skrll .fp_uart_freq = rk3328_platform_uart_freq, 244 1.17 skrll .fp_mpstart = arm_fdt_cpu_mpstart, 245 1.1 jmcneill }; 246 1.1 jmcneill 247 1.17 skrll FDT_PLATFORM(rk3328, "rockchip,rk3328", &rk3328_platform); 248 1.1 jmcneill 249 1.1 jmcneill #endif /* SOC_RK3328 */ 250 1.3 jmcneill 251 1.3 jmcneill 252 1.3 jmcneill #ifdef SOC_RK3399 253 1.3 jmcneill 254 1.3 jmcneill #include <arm/rockchip/rk3399_platform.h> 255 1.3 jmcneill 256 1.3 jmcneill static const struct pmap_devmap * 257 1.3 jmcneill rk3399_platform_devmap(void) 258 1.3 jmcneill { 259 1.3 jmcneill static const struct pmap_devmap devmap[] = { 260 1.3 jmcneill DEVMAP_ENTRY(RK3399_CORE_VBASE, 261 1.3 jmcneill RK3399_CORE_PBASE, 262 1.3 jmcneill RK3399_CORE_SIZE), 263 1.3 jmcneill DEVMAP_ENTRY_END 264 1.3 jmcneill }; 265 1.3 jmcneill 266 1.3 jmcneill return devmap; 267 1.3 jmcneill } 268 1.3 jmcneill 269 1.3 jmcneill void rk3399_platform_early_putchar(char); 270 1.3 jmcneill 271 1.3 jmcneill void 272 1.3 jmcneill rk3399_platform_early_putchar(char c) 273 1.3 jmcneill { 274 1.3 jmcneill #ifdef CONSADDR 275 1.3 jmcneill #define CONSADDR_VA ((CONSADDR - RK3399_CORE_PBASE) + RK3399_CORE_VBASE) 276 1.3 jmcneill volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 277 1.3 jmcneill (volatile uint32_t *)CONSADDR_VA : 278 1.3 jmcneill (volatile uint32_t *)CONSADDR; 279 1.3 jmcneill 280 1.3 jmcneill while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0) 281 1.3 jmcneill ; 282 1.3 jmcneill 283 1.3 jmcneill uartaddr[com_data] = htole32(c); 284 1.3 jmcneill #undef CONSADDR_VA 285 1.3 jmcneill #endif 286 1.3 jmcneill } 287 1.3 jmcneill 288 1.3 jmcneill static u_int 289 1.3 jmcneill rk3399_platform_uart_freq(void) 290 1.3 jmcneill { 291 1.3 jmcneill return RK3399_UART_FREQ; 292 1.3 jmcneill } 293 1.3 jmcneill 294 1.17 skrll static const struct fdt_platform rk3399_platform = { 295 1.17 skrll .fp_devmap = rk3399_platform_devmap, 296 1.17 skrll .fp_bootstrap = rk_platform_bootstrap, 297 1.17 skrll .fp_init_attach_args = rk_platform_init_attach_args, 298 1.17 skrll .fp_device_register = rk_platform_device_register, 299 1.17 skrll .fp_reset = psci_fdt_reset, 300 1.17 skrll .fp_delay = gtmr_delay, 301 1.17 skrll .fp_uart_freq = rk3399_platform_uart_freq, 302 1.17 skrll .fp_mpstart = arm_fdt_cpu_mpstart, 303 1.3 jmcneill }; 304 1.3 jmcneill 305 1.17 skrll FDT_PLATFORM(rk3399, "rockchip,rk3399", &rk3399_platform); 306 1.3 jmcneill 307 1.3 jmcneill #endif /* SOC_RK3399 */ 308 1.16 ryo 309 1.16 ryo 310 1.16 ryo #ifdef SOC_RK3588 311 1.16 ryo 312 1.16 ryo #include <arm/rockchip/rk3588_platform.h> 313 1.16 ryo 314 1.16 ryo static const struct pmap_devmap * 315 1.16 ryo rk3588_platform_devmap(void) 316 1.16 ryo { 317 1.16 ryo static const struct pmap_devmap devmap[] = { 318 1.16 ryo DEVMAP_ENTRY( 319 1.16 ryo RK3588_CORE_VBASE, 320 1.16 ryo RK3588_CORE_PBASE, 321 1.16 ryo RK3588_CORE_SIZE), 322 1.16 ryo DEVMAP_ENTRY_END 323 1.16 ryo }; 324 1.16 ryo 325 1.16 ryo return devmap; 326 1.16 ryo } 327 1.16 ryo 328 1.16 ryo void rk3588_platform_early_putchar(char); 329 1.16 ryo 330 1.16 ryo void 331 1.16 ryo rk3588_platform_early_putchar(char c) 332 1.16 ryo { 333 1.16 ryo #ifdef CONSADDR 334 1.16 ryo #define CONSADDR_VA ((CONSADDR - RK3588_CORE_PBASE) + RK3588_CORE_VBASE) 335 1.16 ryo volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? 336 1.16 ryo (volatile uint32_t *)CONSADDR_VA : 337 1.16 ryo (volatile uint32_t *)CONSADDR; 338 1.16 ryo 339 1.16 ryo while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0) 340 1.16 ryo ; 341 1.16 ryo 342 1.16 ryo uartaddr[com_data] = htole32(c); 343 1.16 ryo #undef CONSADDR_VA 344 1.16 ryo #endif 345 1.16 ryo } 346 1.16 ryo 347 1.16 ryo static u_int 348 1.16 ryo rk3588_platform_uart_freq(void) 349 1.16 ryo { 350 1.16 ryo return RK3588_UART_FREQ; 351 1.16 ryo } 352 1.16 ryo 353 1.17 skrll static const struct fdt_platform rk3588_platform = { 354 1.17 skrll .fp_devmap = rk3588_platform_devmap, 355 1.17 skrll .fp_bootstrap = rk_platform_bootstrap, 356 1.17 skrll .fp_init_attach_args = rk_platform_init_attach_args, 357 1.17 skrll .fp_device_register = rk_platform_device_register, 358 1.17 skrll .fp_reset = psci_fdt_reset, 359 1.17 skrll .fp_delay = gtmr_delay, 360 1.17 skrll .fp_uart_freq = rk3588_platform_uart_freq, 361 1.17 skrll .fp_mpstart = arm_fdt_cpu_mpstart, 362 1.16 ryo }; 363 1.16 ryo 364 1.17 skrll FDT_PLATFORM(rk3588, "rockchip,rk3588", &rk3588_platform); 365 1.16 ryo 366 1.16 ryo #endif /* SOC_RK3588 */ 367 1.16 ryo 368